diff --git a/.cursor/skills/assisted-service-dev-mode/SKILL.md b/.agents/skills/assisted-service-dev-mode/SKILL.md similarity index 100% rename from .cursor/skills/assisted-service-dev-mode/SKILL.md rename to .agents/skills/assisted-service-dev-mode/SKILL.md diff --git a/.agents/skills/assisted-service-verification/SKILL.md b/.agents/skills/assisted-service-verification/SKILL.md new file mode 100644 index 00000000000..3ef3e3ebaca --- /dev/null +++ b/.agents/skills/assisted-service-verification/SKILL.md @@ -0,0 +1,177 @@ +--- +name: assisted-service-verification +description: "MANDATORY: Use this skill BEFORE any git commit, git push, amend, or claiming work is done in the assisted-service repo. Also use when the user asks to test, verify, build, lint, or validate changes. This skill MUST be read and followed before finishing any code change." +--- + +# Assisted Service Verification + +**IMPORTANT: You MUST run at least steps 1-2 of the Quick Verification Checklist below BEFORE committing, amending, or pushing any changes. Do NOT skip verification before git operations.** + +## Quick Verification Checklist + +For most changes, run these in order (stop at first failure): + +``` +1. source .venv/bin/activate && skipper make build-minimal # compilation check (ALWAYS use skipper) +2. source .venv/bin/activate && skipper make lint # linters +3. SKIP_UT_DB=1 go test -v ./path/to/changed/package/... # unit tests for changed packages +4. make unit-test # full unit tests (optional, needs Docker/Podman + DB) +``` + +If generated code was modified (swagger, mocks, CRDs), also run: + +``` +5. source .venv/bin/activate && skipper make generate # regenerate ALL +6. git diff --exit-code # verify no generated code diff +``` + +## Critical Rules + +- **NEVER run bare `go build`, `go test`, or `go vet` for compilation/lint** — they will fail because Go tooling, C headers (nmstate), and dependencies are only available inside the skipper container. +- **ALWAYS use `skipper make `** for build, lint, and generate targets. +- **`go test` can be run directly** ONLY for unit tests of specific packages that don't need nmstate (see list below). Use `SKIP_UT_DB=1` if a DB container is already running at localhost:5433, or the test framework will try to create one. +- **ALWAYS activate the venv first**: `source .venv/bin/activate` before any `skipper` command. + +## Prerequisites + +Skipper requires the Python venv: + +```bash +source .venv/bin/activate +``` + +See the `assisted-service-dev-mode` skill for venv setup if `.venv` doesn't exist. + +## Build + +```bash +source .venv/bin/activate +skipper make build-minimal # build inside skipper container (ALWAYS use this) +``` + +## Code Generation + +### Regenerate mocks only + +```bash +skipper run 'go install go.uber.org/mock/mockgen@v0.6.0 && make generate-mocks' +``` + +Deletes all `mock_*.go` (outside vendor/) then runs `go generate` on all packages. The `mockgen` binary is not pre-installed in the skipper build container, so install it first with `go install` inside the same `skipper run` invocation. Use `skipper run ''` (not `skipper bash`) for arbitrary commands. + +### Regenerate everything + +```bash +skipper make generate +``` + +Runs in order: swagger, go mod tidy/vendor, events, mocks, config, OLM bundle. + +### After modifying swagger.yaml + +```bash +skipper make generate-from-swagger +``` + +### After modifying CRD types in api/ + +```bash +skipper make generate +``` + +## Linting + +```bash +skipper make lint # all linters +skipper make format # auto-format (run before lint to reduce noise) +``` + +## Testing + +### Fast feedback (no database required) + +These packages pass without PostgreSQL or nmstate: + +```bash +go test -v \ + ./pkg/app \ + ./pkg/conversions \ + ./pkg/error \ + ./pkg/filemiddleware \ + ./pkg/jq \ + ./pkg/kafka \ + ./pkg/log \ + ./pkg/mirrorregistries \ + ./pkg/requestid \ + ./pkg/s3wrapper \ + ./pkg/secretdump \ + ./pkg/thread \ + ./pkg/validations \ + ./pkg/webhooks/agentinstall/v1beta1 \ + ./pkg/webhooks/hiveextension/v1beta1 \ + ./internal/cluster/validations +``` + +### Full unit tests (requires Docker/Podman for PostgreSQL) + +```bash +make unit-test +``` + +This starts PostgreSQL at localhost:5433, runs all tests, then stops the DB. + +### Manual DB for repeated test runs + +```bash +# Terminal 1: keep DB running +make run-db-container + +# Terminal 2: run tests repeatedly +SKIP_UT_DB=1 go test -v ./internal/cluster/... +SKIP_UT_DB=1 go test -v ./internal/host/... + +# When done +make kill-db-container +``` + +### Focused tests + +```bash +go test -v ./internal/cluster -run TestClusterName # by test name +FOCUS="install_cluster" make run-unit-test # Ginkgo focus +``` + +## Verify Generated Code (CI Check) + +CI runs `verify-generated-code` which does: + +1. `make generate` (inside the `assisted-service-generate` container image) +2. `git diff --exit-code` — fails if any generated file differs from what's committed + +To reproduce locally: + +```bash +skipper make generate +git diff --exit-code +``` + +**Common causes of failure:** +- Import ordering: `goimports` (run during `generate`) re-sorts imports alphabetically. The `go.uber.org/` prefix sorts *after* `github.com/`, so `go.uber.org/mock/gomock` must appear after all `github.com/` imports within the same import group. +- Stale mocks: If you changed an interface but didn't regenerate mocks. +- Missing `go mod tidy`/`go mod vendor`: If you changed dependencies but didn't re-vendor. + +**Always run `skipper make format` after bulk import changes** to let `gci` and `goimports` fix import ordering automatically. + +## Dependency Change Verification + +After adding, removing, or updating a Go dependency: + +``` +1. go mod tidy +2. go mod vendor +3. go build ./... +4. skipper make generate # regenerate everything +5. git diff --exit-code # verify no generated code diff +6. skipper make lint +7. go test +``` diff --git a/.agents/skills/mgmt-jira/SKILL.md b/.agents/skills/mgmt-jira/SKILL.md new file mode 100644 index 00000000000..7f7daa545e4 --- /dev/null +++ b/.agents/skills/mgmt-jira/SKILL.md @@ -0,0 +1,129 @@ +--- +name: mgmt-jira +description: "Create and manage JIRA issues in the MGMT project for assisted-service. Use when the user asks to file, create, check, view, or update JIRA issues related to assisted-service development." +--- + +# MGMT JIRA Issue Management + +This skill helps manage JIRA issues in the MGMT (KNI Management) project for assisted-service. + +## Project Configuration + +- **Project**: MGMT +- **Cloud ID**: 2b9e35e3-6bd3-4cec-b838-f4249ee02432 +- **Default Component**: Assisted-Installer (ID: 49033) +- **JIRA URL**: https://redhat.atlassian.net + +## Creating Issues + +When the user asks to create a JIRA issue: + +1. **Determine issue type** (default: Story) + - Story (10009): Feature work, enhancements + - Bug (10016): Problems or errors + - Task (10014): Small discrete work items + - Spike (10104): Research tasks + - Epic (10000): Large stories to be broken down + +2. **Use markdown format** for descriptions + - Set `contentFormat: "markdown"` parameter + - Use standard markdown: `##` for headings, backticks for code, `-` for bullets, `|---|---|` for tables + - Do NOT use Jira wiki syntax (`h2.`, `{{code}}`, etc.) + +3. **Set default component** to Assisted-Installer unless specified otherwise + - Component ID: 49033 + - Pass as: `{"components": [{"id": "49033"}]}` + +4. **Return the issue URL** after creation + - Format: https://redhat.atlassian.net/browse/MGMT-XXXXX + +### Example: Create issue from markdown file + +```typescript +mcp__plugin_atlassian_atlassian__createJiraIssue({ + cloudId: "2b9e35e3-6bd3-4cec-b838-f4249ee02432", + projectKey: "MGMT", + issueTypeName: "Story", + summary: "Issue title here", + description: "## Summary\n\n...", + contentFormat: "markdown", + components: [{"id": "49033"}] +}) +``` + +### Available Components + +Common assisted-service components: +- **Assisted-Installer** (49033) - Default, general AI work +- **Assisted-Installer Service** (49094) - Service-specific issues +- **Assisted-Installer Agent** (49081) - Agent-specific issues +- **Assisted-Installer UI (OCM)** (49044) - UI in OCM/SaaS +- **Assisted-Installer CI** (49045) - CI/test infrastructure +- **Assisted-Installer CAPI** (49037) - CAPI integration + +## Viewing Issues + +To check/view an issue: + +```typescript +mcp__plugin_atlassian_atlassian__getJiraIssue({ + cloudId: "2b9e35e3-6bd3-4cec-b838-f4249ee02432", + issueIdOrKey: "MGMT-23599" +}) +``` + +## Updating Issues + +To update an issue: + +```typescript +mcp__plugin_atlassian_atlassian__editJiraIssue({ + cloudId: "2b9e35e3-6bd3-4cec-b838-f4249ee02432", + issueIdOrKey: "MGMT-23599", + contentFormat: "markdown", + fields: { + description: "## Updated description...", + components: [{"id": "49033"}] + } +}) +``` + +## Searching Issues + +To search for issues: + +```typescript +mcp__plugin_atlassian_atlassian__searchJiraIssuesUsingJql({ + cloudId: "2b9e35e3-6bd3-4cec-b838-f4249ee02432", + jql: "project = MGMT AND component = 'Assisted-Installer' AND status = 'To Do'" +}) +``` + +## Common Workflows + +### 1. File issue from documentation + +When user says "create JIRA from docs/dev/issue.md": +1. Read the markdown file +2. Extract title (first heading or filename) +3. Use file content as description +4. Create with default component (Assisted-Installer) +5. Return URL + +### 2. Update issue with component + +When user says "add Assisted Installer component to MGMT-XXXXX": +1. Use editJiraIssue with `{"components": [{"id": "49033"}]}` + +### 3. Check issue status + +When user says "check MGMT-XXXXX": +1. Use getJiraIssue +2. Display: title, status, assignee, description summary + +## Important Notes + +- **Always use markdown format** (`contentFormat: "markdown"`) for new issues and updates +- **Default to Assisted-Installer component** (49033) unless user specifies otherwise +- **Return the issue URL** after creation so user can view it +- **Use Story type** as default unless context suggests Bug, Task, etc. diff --git a/.cursor/skills/assisted-service-dev-mode b/.cursor/skills/assisted-service-dev-mode new file mode 120000 index 00000000000..436c0ee9efd --- /dev/null +++ b/.cursor/skills/assisted-service-dev-mode @@ -0,0 +1 @@ +../../.agents/skills/assisted-service-dev-mode \ No newline at end of file diff --git a/.cursor/skills/assisted-service-verification b/.cursor/skills/assisted-service-verification new file mode 120000 index 00000000000..cd105ab2ea3 --- /dev/null +++ b/.cursor/skills/assisted-service-verification @@ -0,0 +1 @@ +../../.agents/skills/assisted-service-verification \ No newline at end of file diff --git a/.cursor/skills/mgmt-jira b/.cursor/skills/mgmt-jira new file mode 120000 index 00000000000..908f0ed34b5 --- /dev/null +++ b/.cursor/skills/mgmt-jira @@ -0,0 +1 @@ +../../.agents/skills/mgmt-jira \ No newline at end of file