Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 17 additions & 0 deletions actions/plugins-e2e-tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

node_modules/

coverage/
dist/

.*.bun-build

# Editor
.idea
5 changes: 5 additions & 0 deletions actions/plugins-e2e-tests/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

## 0.0.1

- Create new action plugins-e2e-tests to run tests aginst pre-selected stack.
60 changes: 60 additions & 0 deletions actions/plugins-e2e-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Run e2e tests from plugins against specific stack

This is a [GitHub Action][github-action] that help the execution of e2e tests on any plugin against specific selected stacks.
You need to define in which region the selected stack belong, the plugin from where are executed the tests and optionally which other plugins and datasources you want to provision when starting a Grafana instance.
Also, you need to have the **playwright** configuration and the test specifications in the plugin that run the tests and the action will do the rest.
This action use the following input parameters to run:

| Name | Description | Default | Required |
| --------------------- | ----------------------------------------------------------------------------------------------- | ----------------- | -------- |
| `plugin_id` | Name of the plugin running the tests | | Yes |
| `stack_slug` | Name of the stack where you want to run the tests | | Yes |
| `env` | Region of the stack where you want to run the tests | | Yes |
| `other_plugins` | List of other plugins that you want to enable separated by comma | | No |
| `datasource_ids` | List of data sources that you want to enable separated by comma | | No |
| `upload_report_path ` | Name of the folder where you want to store the test report | playwright-report | No |
| `upload_videos_path` | Name of the folder where you want to store the test videos | playwright-videos | No |
| `plugin-secrets` | A JSON string containing key-value pairs of specific plugin secrets necessary to run the tests. | | No |

## Example workflows

This is an example of how you could use this action.

```yml
name: Build and Test PR

on:
pull_request:

jobs:
e2e-tests:
permissions:
contents: write
id-token: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false

- name: Get plugin specific secrets
id: get-secrets
uses: grafana/shared-workflows/actions/get-vault-secrets@5d7e361bc7e0a183cde8afe9899fb7b596d2659b # v1.2.0
with:
repo_secrets: |
MY_SECRET1=test:token1
MY_SECRET2=test:token2

- name: Run e2e cross app tests
id: e2e-cross-apps-tests
uses: grafana/shared-workflows/actions/plugins-e2e-tests@main
with:
stack_slug: "awsintegrationrevamp"
env: "dev-central"
plugin_id: "grafana-csp-app"
other_plugins: "grafana-k8s-app,grafana-asserts-app"
datasource_ids: "grafanacloud-awsintegrationrevamp-prom,grafanacloud-awsintegrationrevamp-logs"
upload_report_path: "playwright-cross-apps-report"
upload_videos_path: "playwright-cross-apps-videos"
plugin-secrets: ${{ ${{ steps.get-secrets.outputs.vault_secrets }} }}
```
167 changes: 167 additions & 0 deletions actions/plugins-e2e-tests/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
name: Run e2e tests
description: Run e2e tests against specific stack and environment
inputs:
plugin_id:
description: "Name of the plugin running the tests"
required: true

stack_slug:
description: "Name of the stack where you want to run the tests"
required: true

env:
description: "Region of the stack where you want to run the tests"
required: true

other_plugins:
description: "List of other plugins that you want to enable separated by comma"
required: false

datasource_ids:
description: "List of data sources that you want to enable separated by comma"
required: false

upload_report_path:
description: "Name of the artifact where you want to store the test report"
required: false
default: "playwright-report"

upload_videos_path:
description: "Name of the artifact where you want to store the test videos"
required: false
default: "playwright-videos"

plugin-secrets:
description: "A JSON string containing key-value paris of specific plugin secrets necessary to run the tests."
required: false

runs:
using: "composite"
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

- name: Setup Node.js environment
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "20"
cache: "yarn"

- name: Install e2e action dependencies
run: yarn install
shell: bash

- uses: google-github-actions/auth@8254fb75a33b976a221574d287e93919e6a36f70 # v2.1.6
id: gcloud-auth
with:
token_format: access_token
workload_identity_provider: "projects/304398677251/locations/global/workloadIdentityPools/github/providers/github-provider"
service_account: "github-cloud-npm-dev-pkgs@grafanalabs-workload-identity.iam.gserviceaccount.com"

- name: NPM registry auth
run: npx google-artifactregistry-auth --credential-config
working-directory: ${{ github.workspace }}
shell: bash

- name: Install plugin dependencies
run: yarn install --immutable --prefer-offline
working-directory: ${{ github.workspace }}
shell: bash

- name: Build frontend
run: yarn run build
working-directory: ${{ github.workspace }}
shell: bash

- name: Get common secrets
id: get-common-secrets
uses: grafana/shared-workflows/actions/get-vault-secrets@5d7e361bc7e0a183cde8afe9899fb7b596d2659b # v1.2.0
with:
common_secrets: |
HG_TOKEN=hg-ci:token

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which HG_TOKEN is added to Vault?

Copy link
Contributor Author

@yduartep yduartep Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a token I generated in the past using the same steps you described in asserts and is working. You can see a successful execution here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my doubt here is that this is a shared workflow that depends on a personal token; technically, I don't really see a problem here, but I just wonder if we can end up with smth more general (not a blocker)


- name: Set plugin secrets as environment variables
id: set-env-vars
if: ${{ inputs.plugin-secrets != '' }}
shell: bash
env:
SECRETS_JSON: "${{ inputs.plugin-secrets }}"
run: |
echo "Parsing and setting plugin environment variables..."
echo "$SECRETS_JSON" | jq -r 'to_entries[] | "echo \"\(.key)=\(.value)\" >> $GITHUB_ENV"' | bash
echo "Plugin environment variables set."

- name: Generate provisioning
shell: bash
run: npx plop e2e-testing-provisioning
working-directory: ${{ github.workspace }}
env:
E2E_STACK_SLUG: ${{ inputs.stack_slug }}
E2E_ENV: ${{ inputs.env }}
HG_TOKEN: ${{ env.HG_TOKEN }}
E2E_PLUGIN_ID: ${{ inputs.plugin_id }}
E2E_OTHER_PLUGINS: ${{ inputs.other_plugins }}
E2E_DATASOURCE_IDS: ${{ inputs.datasource_ids }}

- name: Start server
run: docker compose up -d --build --quiet-pull --timestamps
working-directory: ${{ github.workspace }}
shell: bash

- name: Install Playwright Browsers
run: npx playwright install chromium --with-deps
working-directory: ${{ github.workspace }}
shell: bash

- name: Run Playwright tests
shell: bash
env:
NODE_ENV: production
run: |
echo "Waiting for Grafana to be available..."
timeout=300 # 5 minutes timeout
start_time=$(date +%s)

while ! docker logs grafana-csp-app 2>&1 | grep "Usage stats are ready to report" > /dev/null; do
current_time=$(date +%s)
elapsed=$((current_time - start_time))

if [ $elapsed -ge $timeout ]; then
echo "Timeout reached: Grafana did not become ready within 5 minutes."
exit 1
fi

echo "Waiting for Grafana..."
sleep 5 # Wait for 5 seconds before checking again
done

echo "Grafana is ready!"
npx playwright test
working-directory: ${{ github.workspace }}

- name: Stop grafana docker
run: docker compose down
working-directory: ${{ github.workspace }}
shell: bash

- name: Upload E2E report
uses: actions/upload-artifact@v4
if: always()
with:
name: ${{ inputs.upload_report_path }}
path: playwright-report/
retention-days: 30

- name: Upload E2E videos
uses: actions/upload-artifact@v4
if: always()
with:
name: ${{ inputs.upload_videos_path }}
path: test-results/
retention-days: 30

branding:
icon: "shield"
color: "green"
30 changes: 30 additions & 0 deletions actions/plugins-e2e-tests/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "plugins-e2e-tests",
"version": "0.0.1",
"description": "Run e2e tests from plugins against specific stack and environment.",
"private": true,
"scripts": {},
"keywords": [
"e2e",
"github-action",
"playwright"
],
"author": "",
"license": "ISC",
"dependencies": {
"js-yaml": "^4.1.0",
"plop": "^4.0.1"
},
"devDependencies": {
"@types/bun": "1.2.22",
"@eslint/js": "9.35.0",
"@types/eslint__js": "9.14.0",
"eslint": "9.35.0",
"eslint-config-prettier": "10.1.8",
"eslint-plugin-jest": "29.0.1",
"eslint-plugin-prettier": "5.5.4",
"prettier": "3.6.2",
"typescript": "5.9.2",
"typescript-eslint": "8.44.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
services:
grafana:
environment:
- GF_PLUGINS_PREINSTALL_SYNC={{{GF_PLUGINS_PREINSTALL_SYNC}}}
- GF_GRAFANA_COM_SSO_API_TOKEN={{{GF_GRAFANA_COM_SSO_API_TOKEN}}}
- GF_GRAFANA_COM_URL={{{GF_GRAFANA_COM_URL}}}
- GF_GRAFANA_COM_API_URL={{{GF_GRAFANA_COM_API_URL}}}

container_name: "{{{GF_PLUGIN_ID}}}"
restart: on-failure
platform: "linux/amd64"
build:
context: ./.config
args:
grafana_image: ${GRAFANA_IMAGE:-grafana-enterprise}
grafana_version: ${GRAFANA_VERSION:-main}
ports:
- 3000:3000/tcp
volumes:
- ./dist:/var/lib/grafana/plugins/{{{GF_PLUGIN_ID}}}
- ./provisioning:/etc/grafana/provisioning
- ./provisioning/grafana.ini:/etc/grafana/grafana.ini
- ./provisioning/license.jwt:/etc/grafana/license.jwt
Loading
Loading