Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
ffeabcd
Add MicroVM helper to start Docker without systemd
cursoragent Jul 2, 2026
ad74639
Add MicroVM provisioning scripts and no-systemd PSMDB path
cursoragent Jul 2, 2026
4a191f7
Add MicroVM QA runbook and DOCKER_ENV_VARIABLE in provision script
cursoragent Jul 2, 2026
db1b124
Add temporary automation prompt draft for MicroVM QA agent
cursoragent Jul 2, 2026
ed21b29
Remove temporary AUTOMATION-PROMPT.md
cursoragent Jul 2, 2026
4119cbc
Fix pbm-agent persistence in no-systemd entrypoint for MicroVM backups
cursoragent Jul 2, 2026
f1e8b28
Add PMM UI login script and dual-runtime pmmLogin workflow
cursoragent Jul 2, 2026
575f8fc
Print pmm-ui-login.sh hint after provision-pmm.sh completes
cursoragent Jul 2, 2026
b4756d1
Default pmm-ui-login.sh to headed mode for screen recordings
cursoragent Jul 2, 2026
fe25f32
Harden headed browser default for pmm-ui-login.sh
cursoragent Jul 2, 2026
295b964
Maximize browser window for PMM UI login recordings
cursoragent Jul 2, 2026
9bc8cb3
Make pmm-framework setups work on MicroVM (batch 1)
cursoragent Jul 3, 2026
8c3fa9e
Update SETUP-INVENTORY verification status
cursoragent Jul 3, 2026
40883e3
Consolidate Cursor VM detection to IS_CURSOR_VM
cursoragent Jul 3, 2026
f9280a3
Fix external cleanup and mysql container reuse on MicroVM
cursoragent Jul 3, 2026
bf3f40c
Fix mysql multi-node provisioning on MicroVM
cursoragent Jul 3, 2026
3803d24
Update MicroVM setup verification status for IS_CURSOR_VM
cursoragent Jul 3, 2026
96c7497
Fix pdpgsql Ansible includes and postgresql replication config paths
cursoragent Jul 3, 2026
d908405
Fix postgresql replication data dir cleanup on MicroVM
cursoragent Jul 3, 2026
3dea6ef
Harden mlaunch cleanup and add failed-setup rerun script
cursoragent Jul 3, 2026
ea60b9b
Default IS_CURSOR_VM=1 in batch runners and fix pgsql cleanup
cursoragent Jul 3, 2026
37cade5
Install percona-xtrabackup-80 for PXC 8.0 cluster startup
cursoragent Jul 3, 2026
7364273
Add local mongodb_user_setup.js and fix patroni stop on MicroVM
cursoragent Jul 3, 2026
183fa8a
Add run-final-failures.sh for remaining setup retests
cursoragent Jul 3, 2026
1d6eab4
Fix remaining MicroVM setup failures for patroni, pxc, and ssl_mlaunch
cursoragent Jul 3, 2026
aa6fa71
Add MicroVM no-systemd override for ssl_psmdb diffauth setup
cursoragent Jul 3, 2026
8c5df54
Fix patroni sequential startup and ssl_mlaunch tarball fallbacks
cursoragent Jul 3, 2026
ccd1852
Fix patroni replica startup: clear stale PG socket locks
cursoragent Jul 3, 2026
f076304
Accept streaming state in patroni replica health checks
cursoragent Jul 3, 2026
856e390
Fix ssl_mlaunch libldap install on Ubuntu jammy
cursoragent Jul 3, 2026
b2d31b4
Make ssl_mlaunch setup idempotent on re-run
cursoragent Jul 3, 2026
7b5f8c0
Fix ssl_mlaunch mongosh TLS user setup for MongoDB 8.0
cursoragent Jul 3, 2026
5ee7297
Update SETUP-INVENTORY with final MicroVM PASS status
cursoragent Jul 3, 2026
af317d9
Merge branch 'main' into cursor/pmm-manual-qa-process-d487
travagliad Jul 3, 2026
6a2fdc3
Require Developers visibility on Jira comments in agent docs.
travagliad Jul 17, 2026
eed7c05
Add versioned PMM cloud agent roles, skills, hooks, and docs
travagliad Jul 28, 2026
237c184
Merge origin/main: resolve AGENTS.md and external_setup.yml conflicts
travagliad Jul 28, 2026
4d93d6a
Split Cursor QA into cursor-qa-integration; refine cloud agent roles …
travagliad Jul 29, 2026
a6ab60f
Tighten healer dedup, revert local-only churn, single AUTOMATIONS doc
travagliad Jul 30, 2026
d8da21c
Add nightly setup runner, allow UI login form, trim duplicate docs
travagliad Jul 31, 2026
7f74030
Merge origin/main: PMM-15265 bash pmm-framework
travagliad Jul 31, 2026
32939bc
Use bash pmm-framework on MicroVM instead of Python fork
travagliad Jul 31, 2026
6471304
Use qa-integration PSMDB scripts with runtime MicroVM patches
cursoragent Aug 1, 2026
5782fff
Fix MicroVM PSMDB volume paths and MySQL startup on no-systemd
cursoragent Aug 1, 2026
6bd0151
Use systemctl shim path in patched PSMDB configure scripts
cursoragent Aug 1, 2026
8116352
Make PSMDB MicroVM helper scripts executable; invoke shim via bash
cursoragent Aug 1, 2026
9ba83a0
Collapse MicroVM setup into qa-integration; slim cursor to scripts only
cursoragent Aug 1, 2026
44738cb
Fix is_cursor_vm when both IS_CURSOR_VM and PMM_QA_NO_SYSTEMD are set
cursoragent Aug 1, 2026
f563949
Fix MicroVM detection and valkey ansible docker bootstrap
cursoragent Aug 1, 2026
d31aa0c
Clean valkey volumes between nightly setup runs
cursoragent Aug 1, 2026
9eb9aee
Remove cursor-qa-integration; MicroVM setup is environment + pmm-fram…
cursoragent Aug 1, 2026
a44b857
Scope agent PR to .cursor/ only; revert all qa-integration MicroVM forks
cursoragent Aug 2, 2026
4442263
Replace docker-systemd QA containers with ubuntu + systemctl shim
cursoragent Aug 2, 2026
3b7b30e
Revert non-surgical qa-integration docker-systemd workarounds
cursoragent Aug 2, 2026
0e90913
Use ubuntu keep-alive containers and PSMDB entrypoint without systemd
cursoragent Aug 2, 2026
08d8c53
Fix nightly setups: shim path, PSMDB pmm-agent, PXC umask
cursoragent Aug 2, 2026
72e5ed5
Make mysql systemctl shim restart force-stop mysqld
cursoragent Aug 2, 2026
eebc703
Load PS my.cnf via mysql.conf.d and harden mysql shim restart
cursoragent Aug 2, 2026
b2709c1
chmod 644 MySQL my.cnf after docker cp
cursoragent Aug 2, 2026
9a31bff
Handle systemctl stop postgresql in the shim
cursoragent Aug 2, 2026
e8676d2
Allow Docker bridge ranges in Patroni pg_hba replication rules
cursoragent Aug 2, 2026
19ee686
Wait for Patroni Postgres before pmm-admin add
cursoragent Aug 2, 2026
dff3e41
Fix Patroni replica bootstrap race and leftover Postgres
cursoragent Aug 2, 2026
58ebe85
Fix PSMDB sharded and GSSAPI regressions from entrypoint change
cursoragent Aug 3, 2026
15d23e0
Fix PSMDB sharded cluster setup without systemd
cursoragent Aug 3, 2026
36c2921
Apply Vasyl PSMDB version resolver and fix PDPGSQL tc setup
cursoragent Aug 3, 2026
7b088da
Fix PMM-T2222 MongoDB timeout test race after inventory change
cursoragent Aug 3, 2026
9d69bf5
Merge branch 'main' into cursor/pmm-manual-qa-process-d487
travagliad Aug 3, 2026
5de58ce
Fix HAProxy port collision and PSMDB setup timing issues
cursoragent Aug 3, 2026
9e992ed
Simplify setup fixes: drop helpers, keep minimal changes only
cursoragent Aug 3, 2026
5e4b54b
Fix compat 3.9.0 PSMDB build and GSSAPI rs102 flake
cursoragent Aug 3, 2026
59ac369
Revert scheduled_test mongod workaround; fix systemctl shim
cursoragent Aug 3, 2026
c85c3e4
Fix PSMDB systemctl shim stop mongod and patroni service naming
cursoragent Aug 3, 2026
9d64e8d
Fix PSMDB mongod stop/start for real (validated locally)
cursoragent Aug 3, 2026
b4e461a
Fix PSMDB mongod stop staying down and clean systemctl start
cursoragent Aug 3, 2026
e1624f6
Fix @bm-mongo hooks: reconnect mongo after mongod start/stop
cursoragent Aug 3, 2026
883ae98
Fix mongo client leak causing hung jobs and Before hook timeouts
cursoragent Aug 3, 2026
7b8be3d
Fix PSMDB entrypoint busy-loop starving CI machines of CPU
cursoragent Aug 4, 2026
bae4447
Match systemd supervision semantics in PSMDB entrypoint
cursoragent Aug 4, 2026
26951e3
Set an explicit PATH in the systemctl shims and PSMDB entrypoint
cursoragent Aug 4, 2026
01fb4fa
Export EnvironmentFile values when starting pbm-agent
cursoragent Aug 4, 2026
2241e9a
Ignore repeated percona-release downloads from local runs
cursoragent Aug 4, 2026
1596ce4
Generalize the local CI reproduction script to any tag and setup
cursoragent Aug 4, 2026
e5b542d
Run the sleep-infinity containers with --init so orphans get reaped
cursoragent Aug 4, 2026
ae0bdaf
Start the local CI reproduction from a clean environment
cursoragent Aug 4, 2026
8d0cc3c
Drop percona-release downloads committed by accident
cursoragent Aug 4, 2026
966d922
Drop local tooling and changes superseded by the entrypoint fixes
cursoragent Aug 4, 2026
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
5 changes: 5 additions & 0 deletions .cursor/AUTOMATIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Cursor Cloud Automations

Dashboard spec (pointer prompts + canvas sync): **[docs/agents/AUTOMATIONS.md](../docs/agents/AUTOMATIONS.md)**

Agent roles: `.cursor/agents/`. Skills: `.cursor/skills/`.
58 changes: 58 additions & 0 deletions .cursor/agents/test-healer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
name: test-healer
description: Use proactively when Percona-Lab/pmm-submodules FB Tests or CI checks fail — triage product vs test bug, reproduce with the same setup as the FB GitHub workflow, fix percona/pmm-qa, open PR. Trigger on failed gh pr checks, FB test failures, or when asked to heal/fix flaky or broken PMM QA tests.
---

# Test Healer

You are **Test Healer** — PMM FB Tests triage and repair cloud agent.

**Input:** pmm-submodules PR number, Actions run URL, or triggering GitHub workflow event.

## Knowledge (read by path)

| Skill | Path |
|-------|------|
| FB checks, workflow mapping | `.cursor/skills/pmm-fb-tests/SKILL.md` |
| FB workflow provisioning | `.cursor/skills/pmm-provisioning/SKILL.md` |
| Repo map | `.cursor/skills/pmm-repos/SKILL.md` |
| Jira (optional context) | `.cursor/skills/pmm-jira/SKILL.md` |

## Workflow

1. **Evidence** — `gh pr checks <PR> -R Percona-Lab/pmm-submodules`. If all green → exit immediately. Latest FB build only. Map failures to `pmm-qa/.github/workflows/` runners (see `pmm-fb-tests`). Build a **failure list**: every failed check plus each failing test name, spec path, and `@tag` from the Actions log.
2. **Classify** — **Product bug** → stop (no pmm-qa PR). **Test bug** → continue (wrong selector, flaky timing, setup failure, out-of-scope FB red).
3. **Dedup (mandatory — stop if work already in flight)** — Before reproduce, fix, or any new PR:
- List **every** failing test identifier from step 1 (not just one tag — a run can fail 5+ tests).
- Fetch open pmm-qa PRs and read bodies (title alone is not enough):
```bash
gh pr list -R percona/pmm-qa --state open --limit 50 --json number,title,body
```
- For each open PR, look for section `## FB failures fixed (healer)` (or same tests listed in body). If **any** identifier from your failure list already appears in an open PR → **stop immediately**. Do not reproduce, commit, or open a new PR. Reply with that PR URL.
- Also match on `pmm-submodules PR: #<N>` in that section when the trigger is the same submodules PR and the test list overlaps.
- If no open PR covers these failures → continue.
4. **Reproduce** — Same steps as failed FB job. UI: `runner-e2e-tests-codeceptjs.yml` (legacy CodeceptJS) **or** `runner-e2e-tests-playwright.yml` (`e2e_tests/`). CLI: `runner-integration-cli-tests.yml`. **Not** Jenkins staging.
5. **Fix** — Minimal change in `percona/pmm-qa` only. Re-run failed suite until green.
6. **PR** — Open **one** PR on `percona/pmm-qa`. Body **must** include:

```markdown
## FB failures fixed (healer)

- pmm-submodules PR: #<N>
- tests:
- <PMM-Txxxx or spec path> / @tag
- ...
```

List **all** tests fixed in this PR so future runs can dedup via step 3.

## Cleanup

Remove all Docker resources when finished (see `pmm-provisioning` cleanup section or full docker teardown).

## Never

- Fix `percona/pmm` or `percona/grafana` for FB failures
- Clone `pmm-submodules`
- Act on green FB runs
- Start work when an open pmm-qa PR already lists any of the same failing tests
31 changes: 31 additions & 0 deletions .cursor/agents/test-reporter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: test-reporter
description: Use when pmm-submodules FB Tests finish all green — capture FB test evidence and update Jira customfield_10492 (FB test screenshots). Trigger on successful FB checks, green CI on pmm-submodules, or when asked to attach FB screenshot to a PMM Jira ticket.
---

# Test Reporter

You are **Test Reporter** — attach FB test evidence to Jira when all checks pass.

**Input:** pmm-submodules PR number or linked Jira ticket from trigger context.

## Knowledge (read by path)

| Skill | Path |
|-------|------|
| FB checks (green gate) | `.cursor/skills/pmm-fb-tests/SKILL.md` |
| Jira field update, attachments | `.cursor/skills/pmm-jira/SKILL.md` |
| UI screenshot of Actions run | `.cursor/skills/pmm-ui-evidence/SKILL.md` |
| Repo map | `.cursor/skills/pmm-repos/SKILL.md` |

## Workflow

1. **Verify green** — `gh pr checks <PR> -R Percona-Lab/pmm-submodules` — any `fail` → **stop** (no screenshot, no Jira update).
2. **Screenshot** — FB Tests Actions run (not PR checks page). Use **computer use** per `pmm-ui-evidence`.
3. **Update Jira** — `customfield_10492` with run URL and image attachment via Atlassian MCP.

## Never

- Attach green screenshot when checks failed
- Clone `pmm-submodules`
- Post Jira **comments** — this role only updates `customfield_10492` (and attachments). Comments are Test Runner / human QA.
40 changes: 40 additions & 0 deletions .cursor/agents/test-runner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: test-runner
description: Use proactively for PMM manual QA on a Jira ticket — read requirements, verify against code, provision PMM on the cloud VM, execute tests (terminal + UI), post Developers-only Jira results, optionally open a pmm-qa PR. Trigger when the user asks to test a ticket, run QA, verify a PMM fix, or debug manual test steps for PMM-XXXX.
---

# Test Runner

You are **Test Runner** — PMM manual QA cloud agent.

**Input:** Jira key (e.g. `PMM-15196`) from the user, webhook `issueKey`, or Slack/Jira message. Natural language is fine ("please test PMM-15196") — you do not need a rigid slash prefix when the role file is loaded.

## Knowledge (read by path before acting)

| Skill | Path |
|-------|------|
| Jira read/write, visibility | `.cursor/skills/pmm-jira/SKILL.md` |
| FB checks, JNKPercona | `.cursor/skills/pmm-fb-tests/SKILL.md` |
| Docker, MicroVM, pmm-framework | `.cursor/skills/pmm-provisioning/SKILL.md` |
| PR diffs, JSON dashboards | `.cursor/skills/pmm-git-diff/SKILL.md` |
| UI screenshots / recordings | `.cursor/skills/pmm-ui-evidence/SKILL.md` |
| Repo map, gh rules | `.cursor/skills/pmm-repos/SKILL.md` |

Read each file when its step needs it. Do not guess field IDs or setup commands.

## Workflow

1. **Read ticket** — Atlassian MCP: summary, AC, `customfield_10083`, `customfield_10492`, dev links, comments. Cross-check with `pmm-git-diff` on linked `percona/pmm` / `percona/grafana` PRs.
2. **Plan** — Short test plan: criteria, `DOCKER_ENV_VARIABLE`, `CLIENTS` / DB needs, post-provision steps, FB images from latest JNKPercona comment on linked pmm-submodules PR (`gh` only).
3. **Provision** — Follow `pmm-provisioning` skill (`.cursor/environment.json` + `qa-integration/pmm_qa/pmm-framework/pmm-framework`).
4. **Execute** — Terminal for API/CLI; **computer use** for UI per `pmm-ui-evidence`.
5. **Report** — One Jira comment, **Developers visibility only** (see `pmm-jira`). Include pass/fail per criterion, artifact paths, blockers. Do not mark pass if criteria failed.
6. **Automation decision** — After manual QA: if a minimal `pmm-qa` test adds clear value, implement and open PR to `percona/pmm-qa` only. Otherwise stop after Jira comment.

## Never

- Open PRs to `percona/pmm` or `percona/grafana`
- `git clone` `Percona-Lab/pmm-submodules`
- Modify `qa-integration/` in this agent PR (provisioning fixes are separate upstream PRs)
- Trust "How to test" without reading PR diff
- Post public Jira comments on QA results
4 changes: 4 additions & 0 deletions .cursor/environment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"install": "sudo service docker start 2>/dev/null || true; docker info >/dev/null 2>&1 || sudo dockerd >/tmp/dockerd.log 2>&1 & sleep 5; if ! command -v gh >/dev/null 2>&1; then curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg 2>/dev/null; sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg; echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" | sudo tee /etc/apt/sources.list.d/github-cli.list >/dev/null; sudo apt-get update -qq && sudo apt-get install -y gh; fi; npm install -g json-diff; QA_ROOT=\"${PWD}\"; [ -d pmm-qa ] && QA_ROOT=\"${PWD}/pmm-qa\"; cd \"${QA_ROOT}/codeceptjs-e2e\" && npm ci && npx playwright install --with-deps; cd \"${QA_ROOT}/cli\" && npm ci; cd \"${QA_ROOT}/qa-integration/pmm_qa\" && python3 -m venv virtenv && . virtenv/bin/activate && pip install --upgrade pip setuptools && pip install -r requirements.txt 'docker>=7.0.0'; ansible-galaxy collection install -p \"${HOME}/.ansible/collections\" community.docker >/dev/null 2>&1 || true; chmod +x \"${QA_ROOT}/qa-integration/pmm_qa/pmm-framework/pmm-framework\" \"${QA_ROOT}/.cursor/scripts/\"*.sh 2>/dev/null || true",
"start": "TMUX_CONF=/exec-daemon/tmux.portal.conf; if ! docker info >/dev/null 2>&1; then if ! tmux -f \"$TMUX_CONF\" has-session -t =dockerd 2>/dev/null; then tmux -f \"$TMUX_CONF\" new-session -d -s dockerd -c /tmp -- sudo dockerd; fi; for _ in $(seq 1 30); do [ -S /var/run/docker.sock ] && break; sleep 1; done; docker info >/dev/null 2>&1 || sudo chmod 666 /var/run/docker.sock; fi; export ANSIBLE_COLLECTIONS_PATH=\"${HOME}/.ansible/collections:${ANSIBLE_COLLECTIONS_PATH:-/usr/lib/python3/dist-packages/ansible_collections}\""
}
19 changes: 19 additions & 0 deletions .cursor/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": 1,
"hooks": {
"beforeShellExecution": [
{
"command": ".cursor/hooks/block-pmm-submodules-clone.sh",
"matcher": "git clone",
"failClosed": false
}
],
"stop": [
{
"type": "prompt",
"prompt": "If this run performed PMM QA (test-runner or test-reporter role) and reported results to Jira, confirm a comment was added with Developers-only visibility (not public). If results were produced but no such Jira comment exists, return a followup_message instructing the agent to post using .cursor/skills/pmm-jira/SKILL.md visibility rules. Otherwise allow completion. Input: $ARGUMENTS",
"loop_limit": 2
}
]
}
}
16 changes: 16 additions & 0 deletions .cursor/hooks/block-pmm-submodules-clone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Block cloning Percona-Lab/pmm-submodules — use gh only.
input=$(cat)
command=$(echo "$input" | jq -r '.command // empty')

if echo "$command" | grep -qiE 'git\s+clone.*pmm-submodules'; then
echo '{
"permission": "deny",
"user_message": "Cloning pmm-submodules is not allowed. Use gh pr checks and gh api on Percona-Lab/pmm-submodules instead.",
"agent_message": "Never clone pmm-submodules. Use gh only per pmm-repos skill."
}'
exit 0
fi

echo '{ "permission": "allow" }'
exit 0
56 changes: 56 additions & 0 deletions .cursor/scripts/pmm-ui-login.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
# Log into PMM UI via playwright-cli (Cloud Agent / MicroVM).
# Avoids the Grafana login form and self-signed TLS issues.
#
# Usage:
# export PMM_URL='https://127.0.0.1' # optional, default below
# export ADMIN_PASSWORD='pmm3admin!' # optional
# .cursor/scripts/pmm-ui-login.sh PMM-14576
#
# Session name: pmm-<SESSION_ID> (reuse the same id for follow-up UI commands).
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
PW_CONFIG="${REPO_ROOT}/.playwright/cli.config.json"

SESSION_ID="${1:?usage: $0 <SESSION_ID> e.g. PMM-14576}"
PMM_URL="${PMM_URL:-https://127.0.0.1}"
ADMIN_PASSWORD="${ADMIN_PASSWORD:-pmm3admin!}"
PLAYWRIGHT_SESSION="pmm-${SESSION_ID}"

export PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS="${PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS:-1}"
export DISPLAY="${DISPLAY:-:1}"

if ! command -v playwright-cli >/dev/null 2>&1; then
echo "ERROR: playwright-cli not found on PATH" >&2
exit 1
fi

AUTH_TOKEN="$(printf 'admin:%s' "$ADMIN_PASSWORD" | base64 -w0 2>/dev/null || printf 'admin:%s' "$ADMIN_PASSWORD" | base64)"

PW_CLI=(playwright-cli --config="$PW_CONFIG")
OPEN_ARGS=(-s="$PLAYWRIGHT_SESSION" open --headed "$PMM_URL")
if [ "${PMM_UI_HEADED:-1}" = "0" ]; then
OPEN_ARGS=(-s="$PLAYWRIGHT_SESSION" open "$PMM_URL")
fi

"${PW_CLI[@]}" "${OPEN_ARGS[@]}"

PMM_UI_WIDTH="${PMM_UI_WIDTH:-1920}"
PMM_UI_HEIGHT="${PMM_UI_HEIGHT:-1200}"
"${PW_CLI[@]}" -s="$PLAYWRIGHT_SESSION" resize "$PMM_UI_WIDTH" "$PMM_UI_HEIGHT" >/dev/null 2>&1 || true

# shellcheck disable=SC2016
"${PW_CLI[@]}" -s="$PLAYWRIGHT_SESSION" run-code "async page => {
const base = page.url().match(/^https?:\\/\\/[^/]+/)[0];
await page.setExtraHTTPHeaders({ Authorization: 'Basic ${AUTH_TOKEN}' });
await page.route('**/api/user/auth-tokens/rotate', r => r.fulfill({ status: 200, contentType: 'application/json', body: '{}' }));
await page.route('**/v1/users/me', r => r.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ alerting_tour_completed: true, product_tour_completed: true, snoozed_pmm_version: '', user_id: 1 }) }));
await page.route('**/v1/server/updates?force=**', r => r.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ installed: {}, last_check: new Date().toISOString(), latest: {}, update_available: false }) }));
const res = await page.request.post(base + '/graph/login', { data: { user: 'admin', password: '${ADMIN_PASSWORD}' } });
if (res.status() >= 400) throw new Error('Login failed: HTTP ' + res.status() + ' ' + await res.text());
await page.goto(base + '/pmm-ui/help');
}"

echo "PMM UI login OK (session=${PLAYWRIGHT_SESSION}, url=${PMM_URL})"
7 changes: 7 additions & 0 deletions .cursor/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"plugins": {
"atlassian": {
"enabled": true
}
}
}
56 changes: 56 additions & 0 deletions .cursor/skills/pmm-fb-tests/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
name: pmm-fb-tests
description: Analyze Percona-Lab/pmm-submodules FB Tests via gh pr checks, JNKPercona build comments, flaky triage, and map failures to pmm-qa GitHub workflow runners. Use when reading FB test status, finding server/client docker versions, or deciding what failed in FB CI.
---

# PMM FB Tests

**pmm-submodules** — use `gh` only. **Never** `git clone` this repo.

## Collect checks

```bash
gh pr checks <SUBMODULES_PR> -R Percona-Lab/pmm-submodules
```

- **Latest FB build only** — older comments/checks are invalid
- Ignore JNKPercona "API tests have succeded/failed" comments

## JNKPercona build comment (latest only)

```bash
gh api repos/Percona-Lab/pmm-submodules/issues/<PR>/comments \
--jq '[.[] | select(.user.login == "JNKPercona" and (.body | contains("Staging instance:"))) | {created_at, body}] | sort_by(.created_at) | .[-1]'
```

| Field in comment | Use as |
|------------------|--------|
| Server docker | `DOCKER_VERSION` / `PMM_SERVER_IMAGE` |
| Watchtower docker | `WATCHTOWER_VERSION` |
| Client tarball | `CLIENT_VERSION` |
| Client docker | **ignore** for `CLIENT_VERSION` |

## Map failures to workflows

| Failed check pattern | pmm-qa workflow | Runner |
|---------------------|-----------------|--------|
| `@* UI tests` | `fb-e2e-suite.yml` | `runner-e2e-tests-codeceptjs.yml` (legacy) or `runner-e2e-tests-playwright.yml` (`e2e_tests/`) |
| `CLI tests *` | `fb-integration-suite.yml` | `runner-integration-cli-tests.yml` |

Extract `setup_services` / `tags_for_tests` or `services_list` / `cli_tag` from the failed job inputs.

## Flaky triage

Mark each failure: **relevant** (overlaps ticket) / **flaky** / **out of scope**. Only expand manual scope for **relevant** failures.

## Green gate (Test Reporter)

```bash
gh pr checks <PR> -R Percona-Lab/pmm-submodules 2>&1 | grep -E '\tfail\t'
```

Any output → do **not** attach green screenshot to Jira.

## Detail

See [references/fb-tests.md](references/fb-tests.md) (full templates and screenshot workflow).
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,31 @@ Save screenshots to a temp path the user can find (e.g. workspace root or `%TEMP

## Update Jira

### Comment visibility (mandatory)

**Every Jira comment** on `perconadev.atlassian.net` PMM tickets MUST be restricted to the **Developers** role. Omitting visibility posts a **public** comment (visible to reporters/customers) — never do that for QA notes, triage, or test results.

**Always** pass visibility when calling a comment tool:

| MCP server | Tool | Required parameter |
|------------|------|--------------------|
| `user-mcp-atlassian` | `jira_add_comment` | `visibility: "{\"type\":\"role\",\"value\":\"Developers\"}"` |
| `plugin-atlassian-atlassian` | `addCommentToJiraIssue` | `commentVisibility: {"type": "role", "value": "Developers"}` |

Example (`user-mcp-atlassian`):

```json
jira_add_comment(
issue_key: "PMM-14915",
body: "*QA note (dev)* — ...",
visibility: "{\"type\":\"role\",\"value\":\"Developers\"}"
)
```

If the MCP tool does not accept a visibility parameter, **do not post** — show the draft to the user and ask them to paste it with **Restrict to → Developers**.

`jira_update_issue` on custom fields below does **not** use comment visibility (different mechanism).

### Custom fields

| Field | ID | Use |
Expand Down
41 changes: 41 additions & 0 deletions .cursor/skills/pmm-git-diff/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
name: pmm-git-diff
description: Read and summarize git diffs for percona/pmm and percona/grafana PRs linked to a PMM Jira ticket. Use before planning manual QA or when Test Runner needs PR scope. Includes JSON dashboard diff guidance.
---

# PMM git diff

Read `.cursor/skills/pmm-repos/SKILL.md` for repo rules. Never clone `pmm-submodules`.

## Find and diff PRs

```bash
gh search prs "<JIRA_KEY>" --repo percona/pmm --json number,title,url
gh search prs "<JIRA_KEY>" --repo percona/grafana --json number,title,url
gh pr diff <n> --repo percona/pmm
```

Return: files changed, behavioral summary, gaps in "How to test", suggested manual checks.

## Large Grafana dashboard JSON diffs

Grafana PRs often change dashboard JSON under `grafana/public/` or packaged dashboards. A raw `gh pr diff` can be **thousands of lines** of minified JSON — do not read the full diff inline.

1. List changed JSON files: `gh pr diff <n> --repo percona/grafana --name-only | grep -E '\.json$'`
2. For each file, use a structural JSON diff tool (installed in the PMM cloud environment):

```bash
gh pr diff <n> --repo percona/grafana -- path/to/dashboard.json | json-diff /dev/stdin
# or save base/head and compare:
json-diff base.json head.json
```

3. Summarize **what panels/queries/alerts changed**, not every byte.

`json-diff` is installed globally via `.cursor/environment.json` (`npm install -g json-diff`).

## When diff is too large even for json-diff

- Read the PR description and linked Jira AC first
- Use `gh api` to fetch only the files list and line change counts
- Ask the dev for a testing focus if dashboard churn is unrelated to the ticket
Loading
Loading