[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71MJJDSH8ESZ7G7JMSE2RWH":3,"skill-same:01M71MJJDSH8ESZ7G7JMSE2RWH":87},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":47,"linkOnly":48,"markdownContent":49,"markdownBody":50,"frontMatter":51,"refName":56,"commitSha":57,"skillDirectory":58,"forksCount":14,"repositoryHtmlUrl":59,"repositoryHomepageUrl":60,"ownerHtmlUrl":61,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":62,"install":63,"resources":76},"01M71MJJDSH8ESZ7G7JMSE2RWH","ci-cd-integration",null,"Design CI\u002FCD pipelines that run test suites. Covers GitHub Actions and GitLab CI templates, parallelism and sharding, artifact management, flaky-test quarantine, test-result publishing, coverage quality gates, OIDC keyless deploy, and copy-paste workflows for Playwright, Jest, and multi-stage pipelines. Use when: \"CI\u002FCD,\" \"GitHub Actions,\" \"pipeline,\" \"test in CI,\" \"GitLab CI,\" \"continuous integration,\" \"test automation pipeline,\" \"shard tests in CI.\" Not for: per-test flaky healing at runtime — use test-reliability; go\u002Fno-go release decisions and smoke-test checklists — use release-readiness; test-result dashboards and trend reporting — use qa-metrics. Related: playwright-automation, qa-metrics, test-reliability, coverage-analysis, release-readiness.","pattanation\u002FNorvik","pattanation","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F235419268?v=4","01M71M5THHYYB15ME8R2E4FCZG","Patta","01M71M5TJM1NDM992M8PDKYR2K",0,"MIT","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fci-cd-integration\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"ci cd integration","ci cd","cd","integration","ci","github actions","go release","at","paste","continuous integration","artifact","jest","reliability","design","actions","release","run","gitlab","workflows","go","2026-11-10 10:56:23",false,"---\nname: ci-cd-integration\ndescription: >-\n  Design CI\u002FCD pipelines that run test suites. Covers GitHub Actions and GitLab CI\n  templates, parallelism and sharding, artifact management, flaky-test quarantine,\n  test-result publishing, coverage quality gates, OIDC keyless deploy, and copy-paste\n  workflows for Playwright, Jest, and multi-stage pipelines.\n  Use when: \"CI\u002FCD,\" \"GitHub Actions,\" \"pipeline,\" \"test in CI,\" \"GitLab CI,\"\n  \"continuous integration,\" \"test automation pipeline,\" \"shard tests in CI.\"\n  Not for: per-test flaky healing at runtime — use test-reliability; go\u002Fno-go release\n  decisions and smoke-test checklists — use release-readiness; test-result dashboards\n  and trend reporting — use qa-metrics.\n  Related: playwright-automation, qa-metrics, test-reliability, coverage-analysis, release-readiness.\nlicense: MIT\nmetadata:\n  author: kindlmann\n  version: \"2.0\"\n  category: infrastructure\n---\n\n\u003Cobjective>\nA 20-minute serial suite on every push destroys developer velocity; a green pipeline that retries flaky tests three times hides the race condition until it ships. This skill produces CI\u002FCD pipelines that run the right tests at the right trigger, shard them across runners, store traces and reports as evidence, quarantine flaky tests instead of masking them, and gate merges on real coverage numbers. Use this skill when the question is about running tests in a pipeline, not writing them.\n\u003C\u002Fobjective>\n\n## Discovery Questions\n\nCheck `.agents\u002Fqa-project-context.md` first — if it exists, use it and skip anything already answered there (especially `team_maturity` and existing CI conventions). Then:\n\n1. **Which CI platform?** GitHub Actions, GitLab CI, CircleCI, Jenkins? This skill ships templates for GitHub Actions and GitLab CI.\n2. **What test types need to run?** Unit, integration, E2E, visual, performance? Each has different resource and timing needs.\n3. **What is the current CI duration?** Over 10 minutes means parallelism and sharding are mandatory, not optional.\n4. **How many developers push per day?** High-frequency teams need aggressive concurrency cancellation and caching.\n5. **What triggers should run which tests?** Not every push needs a full E2E suite — map triggers to suites before writing YAML.\n\n### Calibrate to team maturity\n\nSet `team_maturity` in `.agents\u002Fqa-project-context.md`; pick the matching pipeline shape:\n\n- **startup** — one job: lint + unit + one E2E smoke on PR. Fast feedback over completeness.\n- **growing** — separate jobs for unit, integration, E2E. Parallelization, artifact uploads, result publishing, flaky quarantine.\n- **established** — full matrix: sharded E2E, multi-environment promotion gates, perf and security scans, deploy-gated checks, SLA-backed pipelines.\n\n---\n\n## Core Principles\n\n1. **Fast feedback: right tests at the right time.** Unit tests on every push (under 2 min). E2E on PRs (under 10 min). Full suite on merge and nightly. The trigger-to-suite map below is the contract.\n2. **Parallel first: shard tests across workers.** A 20-minute serial suite becomes 5 minutes across 4 shards. Always worth the runner cost.\n3. **Artifacts are evidence.** Every run stores traces, screenshots, coverage, and HTML reports. Without artifacts, a CI failure is an undebuggable \"reproduce locally\" cycle.\n4. **Flaky tests need quarantine, not retries.** Retrying hides the problem — the test passes on retry, the report is green, the race condition persists. Move flaky tests to a non-blocking job, track them, fix the root cause.\n5. **Quality gates get stricter toward production.** Define what must pass at each stage; PR gate is fast and cheap, deploy gate is comprehensive.\n6. **Read thresholds from config, not from bash.** Let the test runner enforce coverage via its own `coverageThreshold`\u002F`thresholds` and exit non-zero. Scraping percentages out of stdout with regex is fragile across runner versions.\n\n---\n\n## Pipeline Architecture\n\n```\nPush to branch:   lint+types (30s) → unit (1-2m)\nPR opened:        + integration (2-3m) → E2E sharded (5-8m) → merge report\nMerge to main:    full E2E ∥ visual ∥ perf budget → deploy (OIDC)\nNightly (cron):   full suite + npm audit + axe a11y + flaky quarantine\n```\n\n### What runs when\n\n| Trigger | Tests | Max duration |\n|---------|-------|--------------|\n| Push to branch | lint, type-check, unit | 2 min |\n| PR opened\u002Fupdated | + integration, E2E smoke | 10 min |\n| Merge to main | + full E2E, visual, perf budget | 15 min |\n| Nightly schedule | full suite, security, a11y, flaky quarantine | 30 min |\n| Release tag | full suite, smoke against staging | 20 min |\n\n---\n\n## GitHub Actions\n\nFor complete copy-paste workflow files (unit, sharded Playwright E2E, full pipeline, nightly, PR gate), see `references\u002Fgithub-actions-templates.md`.\n\n### Action versions (June 2026)\n\nPin to the current major and let Dependabot bump them. The `actions\u002F*` family runs on the Node 24 runner; Node 20 is deprecated on GH-hosted runners.\n\n| Action | Current major | Notes |\n|--------|---------------|-------|\n| `actions\u002Fcheckout` | `@v6` | |\n| `actions\u002Fsetup-node` | `@v6` | v5+ auto-caches only when `packageManager` is set; use `cache: npm` to be explicit |\n| `actions\u002Fcache` | `@v5` | new cache service v2 backend |\n| `actions\u002Fupload-artifact` | `@v7` | v7 can upload unzipped (`archive: false`) |\n| `actions\u002Fdownload-artifact` | `@v7` | pair with upload-artifact major |\n| `dorny\u002Ftest-reporter` | `@v3` | v3 requires Node 24 runner; reporter keys unchanged |\n| `dorny\u002Fpaths-filter` | `@v3` | |\n| `marocchino\u002Fsticky-pull-request-comment` | `@v3` | |\n| `slackapi\u002Fslack-github-action` | `@v2` | floating major; see notification note before adopting v3 |\n\nFor supply-chain-sensitive pipelines, pin third-party actions (dorny, marocchino, slackapi, knapsack) to a full-length commit SHA with a version comment, and let Dependabot update the SHA: `uses: dorny\u002Ftest-reporter@\u003C40-char-sha> # v3.0.0`. First-party `actions\u002F*` are lower risk; tags are acceptable there.\n\n### Key concepts\n\n**Concurrency groups** cancel wasted runs when a branch gets multiple pushes:\n\n```yaml\nconcurrency:\n  group: tests-${{ github.ref }}\n  cancel-in-progress: true\n```\n\n**Matrix sharding** across runners:\n\n```yaml\nstrategy:\n  fail-fast: false\n  matrix:\n    shard: [1, 2, 3, 4]\nsteps:\n  - run: npx playwright test --shard=${{ matrix.shard }}\u002F4\n```\n\n**Caching** browsers so they aren't re-downloaded every run:\n\n```yaml\n- uses: actions\u002Fsetup-node@v6\n  with: { node-version: 22, cache: npm }\n\n- name: Cache Playwright browsers\n  id: playwright-cache\n  uses: actions\u002Fcache@v5\n  with:\n    path: ~\u002F.cache\u002Fms-playwright\n    key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}\n\n- name: Install Playwright browsers\n  if: steps.playwright-cache.outputs.cache-hit != 'true'\n  run: npx playwright install --with-deps chromium\n```\n\n**Artifacts** for reports and traces, and **merging sharded reports** into one HTML report — see `references\u002Fgithub-actions-templates.md` (E2E workflow). The merge job uses `actions\u002Fdownload-artifact@v7` with `pattern: test-results-*` then `npx playwright merge-reports --reporter=html`.\n\n### Smarter sharding at scale\n\nPast 10–15 shards, naïve hash-based splitting wastes runner time on uneven shards. Use a timing-aware balancer:\n\n- **`knapsack-pro`** — timing-data based, supports Playwright\u002FJest\u002FCypress\u002FRSpec; distributes by historical duration.\n- **CloudBees Smart Tests** (formerly **Launchable**) — ML prioritization + Test Impact Analysis; runs only the tests likely to fail for the diff.\n- **Datadog Test Optimization** — TIA + flake management; shard-balancing by historical time.\n- **Trunk Flaky Tests** — flake-aware quarantine + retry budgeting.\n\nBefore reaching for a paid balancer: Playwright's `--shard` already distributes by file and balances on duration from prior runs. To inspect or feed custom timing data, dump it yourself — `npx playwright test --reporter=json | jq '[.suites[].specs[] | {file: .file, duration: .tests[].results[].duration}]'`. For Jest, `jest-slow-test-reporter` surfaces the slowest specs so you can split or fix them.\n\nFor self-hosted runners on Kubernetes, use **Actions Runner Controller** (`arc-runner-set` \u002F `gha-runner-scale-set`) — Helm-installed, auto-scales runner pods per workflow. Replaces the deprecated `runner-deployment` CRD.\n\n### Required status checks\n\nProtect main in Settings → Branches → Branch protection rules: enable \"Require status checks to pass before merging,\" add `lint`, `unit-tests`, and `e2e` (all shards) as required checks, and enable \"Require branches to be up to date.\"\n\n---\n\n## GitLab CI\n\nFor the full pipeline, see `references\u002Fgitlab-ci-template.md`. Key points:\n\n- Stages `[validate, test, e2e, deploy]`; `node:22-alpine` for lint\u002Funit, `mcr.microsoft.com\u002Fplaywright:v1.60.0-noble` for E2E (keep this pinned to your installed `@playwright\u002Ftest` minor).\n- Parallel sharding: `parallel: 4` exposes `CI_NODE_INDEX`\u002F`CI_NODE_TOTAL`; run `npx playwright test --shard=$CI_NODE_INDEX\u002F$CI_NODE_TOTAL`.\n- Coverage: emit a cobertura `coverage_report` artifact and a `junit` report; GitLab reads the percentage and test results from those. The legacy `coverage:` stdout regex is a fragile fallback across Jest versions — prefer the cobertura report.\n\n---\n\n## Advanced Patterns\n\n### Test result publishing to PR comments\n\n```yaml\n- name: Publish test results\n  uses: dorny\u002Ftest-reporter@v3\n  if: ${{ !cancelled() }}\n  with:\n    name: Test Results\n    path: test-results\u002Fjunit.xml\n    reporter: jest-junit  # use java-junit for a Playwright JUnit report\n```\n\nFor the sticky coverage PR comment (`marocchino\u002Fsticky-pull-request-comment@v3`), see `references\u002Fgithub-actions-templates.md` (PR Quality Gate).\n\n### Conditional test execution\n\nOnly test what changed. Use `dorny\u002Fpaths-filter@v3` to set outputs, then gate steps on them — see `references\u002Fgithub-actions-templates.md` (Conditional execution).\n\n### Flaky test quarantine\n\nSeparate flaky tests into a non-blocking job so they run in CI but don't block merges:\n\n```yaml\ne2e-stable:        # required for merge\n  steps:\n    - run: npx playwright test --grep-invert @flaky\n\ne2e-quarantine:    # non-blocking\n  continue-on-error: true\n  steps:\n    - run: npx playwright test --grep @flaky\n    - if: failure()\n      run: echo \"::warning::Quarantined tests failed. Review and fix or remove.\"\n```\n\nTag flaky tests at the source so the grep splits them:\n\n```typescript\ntest('sometimes fails due to race condition @flaky', async ({ page }) => {\n  \u002F\u002F runs in CI but doesn't block merges\n});\n```\n\nIf a quarantined test passes 10 consecutive runs, remove the `@flaky` tag. For runtime self-healing of a single flaky test (selector recovery, auto-retry policy), use `test-reliability`.\n\n### Cache strategies\n\n| Layer | Path | Cache key |\n|-------|------|-----------|\n| Node modules | (handled by `setup-node` `cache: npm`) | automatic |\n| Playwright browsers | `~\u002F.cache\u002Fms-playwright` | `pw-{os}-{hash(package-lock.json)}` |\n| Build cache (Next.js) | `.next\u002Fcache` | `nextjs-{os}-{hash(lockfile)}-{hash(src)}` |\n| Test fixtures | `e2e\u002Ffixtures\u002F.cache` | `test-data-{hash(seed.sql)}` |\n\nUse `actions\u002Fcache@v5` for layers 2–4; add `restore-keys` on build caches for partial matches.\n\n### OIDC keyless deploy\n\nDon't store a long-lived `DEPLOY_TOKEN`. Use GitHub Actions OIDC to assume a cloud role for short-lived credentials — nothing static to leak or rotate:\n\n```yaml\ndeploy:\n  permissions:\n    id-token: write   # request the OIDC JWT\n    contents: read\n  steps:\n    - uses: aws-actions\u002Fconfigure-aws-credentials@v6\n      with:\n        role-to-assume: arn:aws:iam::123456789012:role\u002Fgha-deploy\n        aws-region: eu-central-1\n    - run: .\u002Fdeploy.sh production   # uses short-lived STS creds, no static secret\n```\n\nThe IAM role's trust policy pins the `sub` claim to your repo and branch. GCP (`google-github-actions\u002Fauth`) and Azure (`azure\u002Flogin`) have equivalent OIDC flows.\n\n### Slack\u002FTeams notification on failure\n\nUse `slackapi\u002Fslack-github-action@v2` with `webhook-type: incoming-webhook`, gated on `if: failure() && github.ref == 'refs\u002Fheads\u002Fmain'` so only main-branch failures notify. Before moving to `@v3`, note v3 changed payload handling for workflow-trigger webhooks (no longer flattened\u002Fstringified) — verify your payload against the v3 docs first. Full example in `references\u002Fgithub-actions-templates.md` (Nightly Full Suite).\n\n---\n\n## Quality Gates\n\n| Gate | When | Required checks | Blocking? |\n|------|------|-----------------|-----------|\n| **PR Gate** | PR opened\u002Fupdated | lint, type-check, unit, coverage threshold | Yes |\n| **Merge Gate** | Before merge to main | + E2E smoke suite | Yes |\n| **Deploy Gate** | Before production deploy | + full E2E, visual, perf budget | Yes |\n| **Nightly Gate** | Scheduled 2am daily | full suite, npm audit, axe a11y | Alert only |\n\n### PR Gate (under 3 minutes)\n\nEnforce the coverage floor in the test runner's config, not in bash. In `jest.config.js` (or `vitest.config.ts` `coverage.thresholds`):\n\n```javascript\ncoverageThreshold: { global: { lines: 80, statements: 80, branches: 70 } }\n```\n\nThen `jest --coverage` exits non-zero when coverage drops, so the job fails with no extra script. If you must read the number in CI (e.g. to print it), have Jest emit `json-summary` and read the file — there is no `coverage-summary` CLI:\n\n```yaml\n- run: npm test -- --ci --coverage   # exits 1 if below coverageThreshold\n- name: Print coverage (optional)\n  run: |\n    PCT=$(jq '.total.lines.pct' coverage\u002Fcoverage-summary.json)\n    echo \"Line coverage: ${PCT}%\"\n```\n\n(`json-summary` reporter writes `coverage\u002Fcoverage-summary.json`. For nyc\u002Fc8 projects, `nyc report --reporter=text-summary`. The standalone `istanbul` CLI is deprecated — don't use `istanbul report`.)\n\n### Merge Gate (under 10 minutes)\n\nPR Gate + E2E smoke. Configure as required status checks in branch protection.\n\n### Deploy Gate (under 15 minutes)\n\nNeeds `[unit-tests, e2e-tests, visual-tests]`, then a perf budget check (`npx lhci autorun` \u002F `lhci assert --config=lighthouserc.json`) before the OIDC deploy step above.\n\n### Nightly Gate (up to 30 minutes)\n\nFull E2E across all browsers, security scan, a11y audit, flaky quarantine. Wire the security and a11y steps as real jobs, not just prose:\n\n```yaml\n- run: npm audit --audit-level=high   # fails on high\u002Fcritical advisories\n- run: npx playwright test --grep @a11y   # specs that call @axe-core\u002Fplaywright\n```\n\nWhere the `@a11y`-tagged specs use `@axe-core\u002Fplaywright`:\n\n```typescript\nimport AxeBuilder from '@axe-core\u002Fplaywright';\ntest('home page has no a11y violations @a11y', async ({ page }) => {\n  await page.goto('\u002F');\n  const results = await new AxeBuilder({ page }).analyze();\n  expect(results.violations).toEqual([]);\n});\n```\n\nResults go to Slack, not as blocking checks.\n\n---\n\n## Anti-Patterns\n\n### 1. Running all tests on every commit\nA 20-minute full suite on every push destroys velocity. Use the trigger-to-suite map: fast tests on push, comprehensive on PR and merge.\n\n### 2. No artifact storage\nWithout traces, screenshots, and logs, every CI failure becomes a \"reproduce locally\" cycle that wastes hours. Upload artifacts on `if: ${{ !cancelled() }}`.\n\n### 3. Retrying flaky tests without tracking them\n`retries: 3` hides flakiness — the report is green but the race condition persists. Quarantine, track, fix the root cause.\n\n### 4. CI-only failures without local reproduction\nIf a test only fails in CI, document why (timezone, missing env var, screen resolution) and add a script that replicates CI locally with the **same** Playwright image you run in CI — don't pin a stale image. See `references\u002Fgithub-actions-templates.md` (Local repro).\n\n### 5. Shared state between CI jobs\nJobs that read files from sibling jobs without artifacts or `needs`. Each job starts fresh; pass data via `upload-artifact`\u002F`download-artifact`.\n\n### 6. No concurrency controls\nMultiple runs for the same branch waste runners. Always use a concurrency group with `cancel-in-progress: true`.\n\n### 7. Hardcoded secrets in workflow files\nNever put tokens, passwords, or keys in YAML. Use repo secrets (`${{ secrets.X }}`) or GitLab CI\u002FCD variables — and prefer OIDC keyless auth over any long-lived deploy token.\n\n### 8. Ignoring job timeouts\nA stuck test can hold a runner for hours. Set `timeout-minutes` on every job and `actionTimeout`\u002F`navigationTimeout` in the Playwright config.\n\n---\n\n## Verification\n\nProve the pipeline before relying on it. Smallest check first:\n\n1. **Lint the workflow syntax** — `actionlint .github\u002Fworkflows\u002F*.yml` catches expression, `needs`, and shell-quoting errors before they fail at runtime. Add a `yamllint .github\u002Fworkflows\u002F` pass for indentation. Run actionlint as a job too.\n2. **Dry-run a job locally** — `act -j unit-tests` runs the job in a container so you can iterate without pushing.\n3. **Confirm required checks appear** — push to a throwaway branch, open a draft PR, and verify the expected check runs (`lint`, `unit-tests`, `e2e`) show up and that the coverage gate fails when you drop coverage below the threshold.\n4. **Verify artifacts** — download the run's artifacts from the Actions UI (or `gh run download \u003Cid>`) and confirm `playwright-report\u002F` and traces are present.\n\n---\n\n## Done When\n\n- A trigger map exists: push runs lint+unit only; the PR workflow gates E2E behind `if: github.event_name == 'pull_request'` (verify the YAML, not \"integration runs somewhere\").\n- `actionlint .github\u002Fworkflows\u002F*.yml` exits 0.\n- A non-blocking quarantine job runs `--grep @flaky` with `continue-on-error: true`; the stable job runs `--grep-invert @flaky` and is in the required checks list.\n- Test artifacts (reports, screenshots, traces) upload on `if: ${{ !cancelled() }}` with an explicit `retention-days`\u002F`expire_in`.\n- Concurrency groups with `cancel-in-progress: true` are set on the PR\u002Ftest workflows.\n- Coverage is enforced by the runner's `coverageThreshold`\u002F`thresholds` (job exits non-zero below the floor) — no `coverage-summary` CLI scrape.\n- Branch protection lists `lint`, `unit-tests`, and `e2e` as required status checks.\n- No long-lived deploy token in YAML — deploy uses OIDC (`id-token: write` + cloud role) or, at minimum, a secrets-store reference.\n\n---\n\n## Related Skills\n\n- **playwright-automation** — writing the E2E tests, Page Object Model, and the `playwright.config.ts` whose sharding\u002Ftimeouts this pipeline drives.\n- **test-reliability** — runtime self-healing of one flaky test (selector recovery, retry policy); go there to fix a flaky test, come here to quarantine it in CI.\n- **qa-metrics** — turning the JUnit\u002Fcoverage artifacts this pipeline produces into dashboards and flakiness trends.\n- **release-readiness** — the human go\u002Fno-go decision and release checklist that consumes these gate results; this skill builds the gates, that one decides on them.\n- **coverage-analysis** — finding the coverage gaps and setting the threshold this skill's PR gate enforces.\n\n## Reference Files (in `references\u002F`)\n\n- **github-actions-templates.md** — copy-paste unit, sharded Playwright E2E (+ report merge), full pipeline, nightly (Slack + audit + axe), and PR quality-gate workflows, plus conditional execution and local-repro snippets.\n- **gitlab-ci-template.md** — full `.gitlab-ci.yml` with parallel sharding, cobertura coverage, and JUnit MR reporting.\n","\u003Cobjective>\nA 20-minute serial suite on every push destroys developer velocity; a green pipeline that retries flaky tests three times hides the race condition until it ships. This skill produces CI\u002FCD pipelines that run the right tests at the right trigger, shard them across runners, store traces and reports as evidence, quarantine flaky tests instead of masking them, and gate merges on real coverage numbers. Use this skill when the question is about running tests in a pipeline, not writing them.\n\u003C\u002Fobjective>\n\n## Discovery Questions\n\nCheck `.agents\u002Fqa-project-context.md` first — if it exists, use it and skip anything already answered there (especially `team_maturity` and existing CI conventions). Then:\n\n1. **Which CI platform?** GitHub Actions, GitLab CI, CircleCI, Jenkins? This skill ships templates for GitHub Actions and GitLab CI.\n2. **What test types need to run?** Unit, integration, E2E, visual, performance? Each has different resource and timing needs.\n3. **What is the current CI duration?** Over 10 minutes means parallelism and sharding are mandatory, not optional.\n4. **How many developers push per day?** High-frequency teams need aggressive concurrency cancellation and caching.\n5. **What triggers should run which tests?** Not every push needs a full E2E suite — map triggers to suites before writing YAML.\n\n### Calibrate to team maturity\n\nSet `team_maturity` in `.agents\u002Fqa-project-context.md`; pick the matching pipeline shape:\n\n- **startup** — one job: lint + unit + one E2E smoke on PR. Fast feedback over completeness.\n- **growing** — separate jobs for unit, integration, E2E. Parallelization, artifact uploads, result publishing, flaky quarantine.\n- **established** — full matrix: sharded E2E, multi-environment promotion gates, perf and security scans, deploy-gated checks, SLA-backed pipelines.\n\n---\n\n## Core Principles\n\n1. **Fast feedback: right tests at the right time.** Unit tests on every push (under 2 min). E2E on PRs (under 10 min). Full suite on merge and nightly. The trigger-to-suite map below is the contract.\n2. **Parallel first: shard tests across workers.** A 20-minute serial suite becomes 5 minutes across 4 shards. Always worth the runner cost.\n3. **Artifacts are evidence.** Every run stores traces, screenshots, coverage, and HTML reports. Without artifacts, a CI failure is an undebuggable \"reproduce locally\" cycle.\n4. **Flaky tests need quarantine, not retries.** Retrying hides the problem — the test passes on retry, the report is green, the race condition persists. Move flaky tests to a non-blocking job, track them, fix the root cause.\n5. **Quality gates get stricter toward production.** Define what must pass at each stage; PR gate is fast and cheap, deploy gate is comprehensive.\n6. **Read thresholds from config, not from bash.** Let the test runner enforce coverage via its own `coverageThreshold`\u002F`thresholds` and exit non-zero. Scraping percentages out of stdout with regex is fragile across runner versions.\n\n---\n\n## Pipeline Architecture\n\n```\nPush to branch:   lint+types (30s) → unit (1-2m)\nPR opened:        + integration (2-3m) → E2E sharded (5-8m) → merge report\nMerge to main:    full E2E ∥ visual ∥ perf budget → deploy (OIDC)\nNightly (cron):   full suite + npm audit + axe a11y + flaky quarantine\n```\n\n### What runs when\n\n| Trigger | Tests | Max duration |\n|---------|-------|--------------|\n| Push to branch | lint, type-check, unit | 2 min |\n| PR opened\u002Fupdated | + integration, E2E smoke | 10 min |\n| Merge to main | + full E2E, visual, perf budget | 15 min |\n| Nightly schedule | full suite, security, a11y, flaky quarantine | 30 min |\n| Release tag | full suite, smoke against staging | 20 min |\n\n---\n\n## GitHub Actions\n\nFor complete copy-paste workflow files (unit, sharded Playwright E2E, full pipeline, nightly, PR gate), see `references\u002Fgithub-actions-templates.md`.\n\n### Action versions (June 2026)\n\nPin to the current major and let Dependabot bump them. The `actions\u002F*` family runs on the Node 24 runner; Node 20 is deprecated on GH-hosted runners.\n\n| Action | Current major | Notes |\n|--------|---------------|-------|\n| `actions\u002Fcheckout` | `@v6` | |\n| `actions\u002Fsetup-node` | `@v6` | v5+ auto-caches only when `packageManager` is set; use `cache: npm` to be explicit |\n| `actions\u002Fcache` | `@v5` | new cache service v2 backend |\n| `actions\u002Fupload-artifact` | `@v7` | v7 can upload unzipped (`archive: false`) |\n| `actions\u002Fdownload-artifact` | `@v7` | pair with upload-artifact major |\n| `dorny\u002Ftest-reporter` | `@v3` | v3 requires Node 24 runner; reporter keys unchanged |\n| `dorny\u002Fpaths-filter` | `@v3` | |\n| `marocchino\u002Fsticky-pull-request-comment` | `@v3` | |\n| `slackapi\u002Fslack-github-action` | `@v2` | floating major; see notification note before adopting v3 |\n\nFor supply-chain-sensitive pipelines, pin third-party actions (dorny, marocchino, slackapi, knapsack) to a full-length commit SHA with a version comment, and let Dependabot update the SHA: `uses: dorny\u002Ftest-reporter@\u003C40-char-sha> # v3.0.0`. First-party `actions\u002F*` are lower risk; tags are acceptable there.\n\n### Key concepts\n\n**Concurrency groups** cancel wasted runs when a branch gets multiple pushes:\n\n```yaml\nconcurrency:\n  group: tests-${{ github.ref }}\n  cancel-in-progress: true\n```\n\n**Matrix sharding** across runners:\n\n```yaml\nstrategy:\n  fail-fast: false\n  matrix:\n    shard: [1, 2, 3, 4]\nsteps:\n  - run: npx playwright test --shard=${{ matrix.shard }}\u002F4\n```\n\n**Caching** browsers so they aren't re-downloaded every run:\n\n```yaml\n- uses: actions\u002Fsetup-node@v6\n  with: { node-version: 22, cache: npm }\n\n- name: Cache Playwright browsers\n  id: playwright-cache\n  uses: actions\u002Fcache@v5\n  with:\n    path: ~\u002F.cache\u002Fms-playwright\n    key: playwright-${{ runner.os }}-${{ hashFiles('package-lock.json') }}\n\n- name: Install Playwright browsers\n  if: steps.playwright-cache.outputs.cache-hit != 'true'\n  run: npx playwright install --with-deps chromium\n```\n\n**Artifacts** for reports and traces, and **merging sharded reports** into one HTML report — see `references\u002Fgithub-actions-templates.md` (E2E workflow). The merge job uses `actions\u002Fdownload-artifact@v7` with `pattern: test-results-*` then `npx playwright merge-reports --reporter=html`.\n\n### Smarter sharding at scale\n\nPast 10–15 shards, naïve hash-based splitting wastes runner time on uneven shards. Use a timing-aware balancer:\n\n- **`knapsack-pro`** — timing-data based, supports Playwright\u002FJest\u002FCypress\u002FRSpec; distributes by historical duration.\n- **CloudBees Smart Tests** (formerly **Launchable**) — ML prioritization + Test Impact Analysis; runs only the tests likely to fail for the diff.\n- **Datadog Test Optimization** — TIA + flake management; shard-balancing by historical time.\n- **Trunk Flaky Tests** — flake-aware quarantine + retry budgeting.\n\nBefore reaching for a paid balancer: Playwright's `--shard` already distributes by file and balances on duration from prior runs. To inspect or feed custom timing data, dump it yourself — `npx playwright test --reporter=json | jq '[.suites[].specs[] | {file: .file, duration: .tests[].results[].duration}]'`. For Jest, `jest-slow-test-reporter` surfaces the slowest specs so you can split or fix them.\n\nFor self-hosted runners on Kubernetes, use **Actions Runner Controller** (`arc-runner-set` \u002F `gha-runner-scale-set`) — Helm-installed, auto-scales runner pods per workflow. Replaces the deprecated `runner-deployment` CRD.\n\n### Required status checks\n\nProtect main in Settings → Branches → Branch protection rules: enable \"Require status checks to pass before merging,\" add `lint`, `unit-tests`, and `e2e` (all shards) as required checks, and enable \"Require branches to be up to date.\"\n\n---\n\n## GitLab CI\n\nFor the full pipeline, see `references\u002Fgitlab-ci-template.md`. Key points:\n\n- Stages `[validate, test, e2e, deploy]`; `node:22-alpine` for lint\u002Funit, `mcr.microsoft.com\u002Fplaywright:v1.60.0-noble` for E2E (keep this pinned to your installed `@playwright\u002Ftest` minor).\n- Parallel sharding: `parallel: 4` exposes `CI_NODE_INDEX`\u002F`CI_NODE_TOTAL`; run `npx playwright test --shard=$CI_NODE_INDEX\u002F$CI_NODE_TOTAL`.\n- Coverage: emit a cobertura `coverage_report` artifact and a `junit` report; GitLab reads the percentage and test results from those. The legacy `coverage:` stdout regex is a fragile fallback across Jest versions — prefer the cobertura report.\n\n---\n\n## Advanced Patterns\n\n### Test result publishing to PR comments\n\n```yaml\n- name: Publish test results\n  uses: dorny\u002Ftest-reporter@v3\n  if: ${{ !cancelled() }}\n  with:\n    name: Test Results\n    path: test-results\u002Fjunit.xml\n    reporter: jest-junit  # use java-junit for a Playwright JUnit report\n```\n\nFor the sticky coverage PR comment (`marocchino\u002Fsticky-pull-request-comment@v3`), see `references\u002Fgithub-actions-templates.md` (PR Quality Gate).\n\n### Conditional test execution\n\nOnly test what changed. Use `dorny\u002Fpaths-filter@v3` to set outputs, then gate steps on them — see `references\u002Fgithub-actions-templates.md` (Conditional execution).\n\n### Flaky test quarantine\n\nSeparate flaky tests into a non-blocking job so they run in CI but don't block merges:\n\n```yaml\ne2e-stable:        # required for merge\n  steps:\n    - run: npx playwright test --grep-invert @flaky\n\ne2e-quarantine:    # non-blocking\n  continue-on-error: true\n  steps:\n    - run: npx playwright test --grep @flaky\n    - if: failure()\n      run: echo \"::warning::Quarantined tests failed. Review and fix or remove.\"\n```\n\nTag flaky tests at the source so the grep splits them:\n\n```typescript\ntest('sometimes fails due to race condition @flaky', async ({ page }) => {\n  \u002F\u002F runs in CI but doesn't block merges\n});\n```\n\nIf a quarantined test passes 10 consecutive runs, remove the `@flaky` tag. For runtime self-healing of a single flaky test (selector recovery, auto-retry policy), use `test-reliability`.\n\n### Cache strategies\n\n| Layer | Path | Cache key |\n|-------|------|-----------|\n| Node modules | (handled by `setup-node` `cache: npm`) | automatic |\n| Playwright browsers | `~\u002F.cache\u002Fms-playwright` | `pw-{os}-{hash(package-lock.json)}` |\n| Build cache (Next.js) | `.next\u002Fcache` | `nextjs-{os}-{hash(lockfile)}-{hash(src)}` |\n| Test fixtures | `e2e\u002Ffixtures\u002F.cache` | `test-data-{hash(seed.sql)}` |\n\nUse `actions\u002Fcache@v5` for layers 2–4; add `restore-keys` on build caches for partial matches.\n\n### OIDC keyless deploy\n\nDon't store a long-lived `DEPLOY_TOKEN`. Use GitHub Actions OIDC to assume a cloud role for short-lived credentials — nothing static to leak or rotate:\n\n```yaml\ndeploy:\n  permissions:\n    id-token: write   # request the OIDC JWT\n    contents: read\n  steps:\n    - uses: aws-actions\u002Fconfigure-aws-credentials@v6\n      with:\n        role-to-assume: arn:aws:iam::123456789012:role\u002Fgha-deploy\n        aws-region: eu-central-1\n    - run: .\u002Fdeploy.sh production   # uses short-lived STS creds, no static secret\n```\n\nThe IAM role's trust policy pins the `sub` claim to your repo and branch. GCP (`google-github-actions\u002Fauth`) and Azure (`azure\u002Flogin`) have equivalent OIDC flows.\n\n### Slack\u002FTeams notification on failure\n\nUse `slackapi\u002Fslack-github-action@v2` with `webhook-type: incoming-webhook`, gated on `if: failure() && github.ref == 'refs\u002Fheads\u002Fmain'` so only main-branch failures notify. Before moving to `@v3`, note v3 changed payload handling for workflow-trigger webhooks (no longer flattened\u002Fstringified) — verify your payload against the v3 docs first. Full example in `references\u002Fgithub-actions-templates.md` (Nightly Full Suite).\n\n---\n\n## Quality Gates\n\n| Gate | When | Required checks | Blocking? |\n|------|------|-----------------|-----------|\n| **PR Gate** | PR opened\u002Fupdated | lint, type-check, unit, coverage threshold | Yes |\n| **Merge Gate** | Before merge to main | + E2E smoke suite | Yes |\n| **Deploy Gate** | Before production deploy | + full E2E, visual, perf budget | Yes |\n| **Nightly Gate** | Scheduled 2am daily | full suite, npm audit, axe a11y | Alert only |\n\n### PR Gate (under 3 minutes)\n\nEnforce the coverage floor in the test runner's config, not in bash. In `jest.config.js` (or `vitest.config.ts` `coverage.thresholds`):\n\n```javascript\ncoverageThreshold: { global: { lines: 80, statements: 80, branches: 70 } }\n```\n\nThen `jest --coverage` exits non-zero when coverage drops, so the job fails with no extra script. If you must read the number in CI (e.g. to print it), have Jest emit `json-summary` and read the file — there is no `coverage-summary` CLI:\n\n```yaml\n- run: npm test -- --ci --coverage   # exits 1 if below coverageThreshold\n- name: Print coverage (optional)\n  run: |\n    PCT=$(jq '.total.lines.pct' coverage\u002Fcoverage-summary.json)\n    echo \"Line coverage: ${PCT}%\"\n```\n\n(`json-summary` reporter writes `coverage\u002Fcoverage-summary.json`. For nyc\u002Fc8 projects, `nyc report --reporter=text-summary`. The standalone `istanbul` CLI is deprecated — don't use `istanbul report`.)\n\n### Merge Gate (under 10 minutes)\n\nPR Gate + E2E smoke. Configure as required status checks in branch protection.\n\n### Deploy Gate (under 15 minutes)\n\nNeeds `[unit-tests, e2e-tests, visual-tests]`, then a perf budget check (`npx lhci autorun` \u002F `lhci assert --config=lighthouserc.json`) before the OIDC deploy step above.\n\n### Nightly Gate (up to 30 minutes)\n\nFull E2E across all browsers, security scan, a11y audit, flaky quarantine. Wire the security and a11y steps as real jobs, not just prose:\n\n```yaml\n- run: npm audit --audit-level=high   # fails on high\u002Fcritical advisories\n- run: npx playwright test --grep @a11y   # specs that call @axe-core\u002Fplaywright\n```\n\nWhere the `@a11y`-tagged specs use `@axe-core\u002Fplaywright`:\n\n```typescript\nimport AxeBuilder from '@axe-core\u002Fplaywright';\ntest('home page has no a11y violations @a11y', async ({ page }) => {\n  await page.goto('\u002F');\n  const results = await new AxeBuilder({ page }).analyze();\n  expect(results.violations).toEqual([]);\n});\n```\n\nResults go to Slack, not as blocking checks.\n\n---\n\n## Anti-Patterns\n\n### 1. Running all tests on every commit\nA 20-minute full suite on every push destroys velocity. Use the trigger-to-suite map: fast tests on push, comprehensive on PR and merge.\n\n### 2. No artifact storage\nWithout traces, screenshots, and logs, every CI failure becomes a \"reproduce locally\" cycle that wastes hours. Upload artifacts on `if: ${{ !cancelled() }}`.\n\n### 3. Retrying flaky tests without tracking them\n`retries: 3` hides flakiness — the report is green but the race condition persists. Quarantine, track, fix the root cause.\n\n### 4. CI-only failures without local reproduction\nIf a test only fails in CI, document why (timezone, missing env var, screen resolution) and add a script that replicates CI locally with the **same** Playwright image you run in CI — don't pin a stale image. See `references\u002Fgithub-actions-templates.md` (Local repro).\n\n### 5. Shared state between CI jobs\nJobs that read files from sibling jobs without artifacts or `needs`. Each job starts fresh; pass data via `upload-artifact`\u002F`download-artifact`.\n\n### 6. No concurrency controls\nMultiple runs for the same branch waste runners. Always use a concurrency group with `cancel-in-progress: true`.\n\n### 7. Hardcoded secrets in workflow files\nNever put tokens, passwords, or keys in YAML. Use repo secrets (`${{ secrets.X }}`) or GitLab CI\u002FCD variables — and prefer OIDC keyless auth over any long-lived deploy token.\n\n### 8. Ignoring job timeouts\nA stuck test can hold a runner for hours. Set `timeout-minutes` on every job and `actionTimeout`\u002F`navigationTimeout` in the Playwright config.\n\n---\n\n## Verification\n\nProve the pipeline before relying on it. Smallest check first:\n\n1. **Lint the workflow syntax** — `actionlint .github\u002Fworkflows\u002F*.yml` catches expression, `needs`, and shell-quoting errors before they fail at runtime. Add a `yamllint .github\u002Fworkflows\u002F` pass for indentation. Run actionlint as a job too.\n2. **Dry-run a job locally** — `act -j unit-tests` runs the job in a container so you can iterate without pushing.\n3. **Confirm required checks appear** — push to a throwaway branch, open a draft PR, and verify the expected check runs (`lint`, `unit-tests`, `e2e`) show up and that the coverage gate fails when you drop coverage below the threshold.\n4. **Verify artifacts** — download the run's artifacts from the Actions UI (or `gh run download \u003Cid>`) and confirm `playwright-report\u002F` and traces are present.\n\n---\n\n## Done When\n\n- A trigger map exists: push runs lint+unit only; the PR workflow gates E2E behind `if: github.event_name == 'pull_request'` (verify the YAML, not \"integration runs somewhere\").\n- `actionlint .github\u002Fworkflows\u002F*.yml` exits 0.\n- A non-blocking quarantine job runs `--grep @flaky` with `continue-on-error: true`; the stable job runs `--grep-invert @flaky` and is in the required checks list.\n- Test artifacts (reports, screenshots, traces) upload on `if: ${{ !cancelled() }}` with an explicit `retention-days`\u002F`expire_in`.\n- Concurrency groups with `cancel-in-progress: true` are set on the PR\u002Ftest workflows.\n- Coverage is enforced by the runner's `coverageThreshold`\u002F`thresholds` (job exits non-zero below the floor) — no `coverage-summary` CLI scrape.\n- Branch protection lists `lint`, `unit-tests`, and `e2e` as required status checks.\n- No long-lived deploy token in YAML — deploy uses OIDC (`id-token: write` + cloud role) or, at minimum, a secrets-store reference.\n\n---\n\n## Related Skills\n\n- **playwright-automation** — writing the E2E tests, Page Object Model, and the `playwright.config.ts` whose sharding\u002Ftimeouts this pipeline drives.\n- **test-reliability** — runtime self-healing of one flaky test (selector recovery, retry policy); go there to fix a flaky test, come here to quarantine it in CI.\n- **qa-metrics** — turning the JUnit\u002Fcoverage artifacts this pipeline produces into dashboards and flakiness trends.\n- **release-readiness** — the human go\u002Fno-go decision and release checklist that consumes these gate results; this skill builds the gates, that one decides on them.\n- **coverage-analysis** — finding the coverage gaps and setting the threshold this skill's PR gate enforces.\n\n## Reference Files (in `references\u002F`)\n\n- **github-actions-templates.md** — copy-paste unit, sharded Playwright E2E (+ report merge), full pipeline, nightly (Slack + audit + axe), and PR quality-gate workflows, plus conditional execution and local-repro snippets.\n- **gitlab-ci-template.md** — full `.gitlab-ci.yml` with parallel sharding, cobertura coverage, and JUnit MR reporting.\n",{"name":5,"license":15,"metadata":52,"description":7},{"author":53,"version":54,"category":55},"kindlmann","2.0","infrastructure","claude\u002Finstall-gsd-build-foQdV","d86cd127f527124b5fd0fd0bc679a4d79b7d01d7",".agents\u002Fskills\u002Fci-cd-integration","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik","https:\u002F\u002Fnorvik-orpin.vercel.app","https:\u002F\u002Fgithub.com\u002Fpattanation","2026-07-17 11:17:04",{"source":8,"skillName":5,"commands":64,"prompt":74,"zipAvailable":75},[65,68,71],{"tool":66,"command":67},"npx","npx skills add pattanation\u002FNorvik --skill ci-cd-integration",{"tool":69,"command":70},"bunx","bunx skills add pattanation\u002FNorvik --skill ci-cd-integration",{"tool":72,"command":73},"pnpm","pnpm dlx skills add pattanation\u002FNorvik --skill ci-cd-integration","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fci-cd-integration\u002FSKILL.md",true,[77,83],{"path":78,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":81,"sourceHtmlUrl":82},"references\u002Fgithub-actions-templates.md","REFERENCE","参考文档",18287,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fci-cd-integration\u002Freferences\u002Fgithub-actions-templates.md",{"path":84,"resourceType":79,"resourceTypeDesc":80,"sizeBytes":85,"sourceHtmlUrl":86},"references\u002Fgitlab-ci-template.md",2455,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fci-cd-integration\u002Freferences\u002Fgitlab-ci-template.md",[88,119,145,168,190,205],{"skillNo":89,"name":90,"nameZh":6,"description":91,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":92,"licenseFileUrl":93,"sourceHtmlUrl":94,"categories":95,"keywords":100,"publishedAt":118},"01M71QDV4DM8T19HEHWATEF1K4","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fwebapp-testing\u002FSKILL.md",[96,97],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117],"webapp","testing","webapp testing","for","applications","local","frontend","debugging","toolkit","logs","browser","with","playwright","web","behavior","ui","screenshots","2026-11-10 13:02:02",{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":92,"licenseFileUrl":123,"sourceHtmlUrl":124,"categories":125,"keywords":127,"publishedAt":118},"01M71QDH2GGMXGA9105C9W1N7B","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fweb-artifacts-builder\u002FSKILL.md",[126],{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},[128,129,130,114,131,132,133,104,134,135,107,136,137,138,139,140,141,142,143,144],"builder","artifacts builder","artifacts","web artifacts builder","single-file","css","Tailwind","ui components","single","use","file","components","react","multi","state","routing","state management",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":149,"sourceHtmlUrl":150,"categories":151,"keywords":153,"publishedAt":118},"01M71QD9T2XC3EWMQNN9ACNWQ1","vueuse-functions","Apply VueUse composables where appropriate to build concise, maintainable Vue.js \u002F Nuxt features.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvueuse-functions\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvueuse-functions\u002FSKILL.md",[152],{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},[154,155,156,157,158,159,160,161,162,163,164,165,166,167],"functions","vueuse","vueuse functions","project","nuxt","apply","github","concise","build","https","features","vue","js","composables",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":172,"sourceHtmlUrl":173,"categories":174,"keywords":177,"publishedAt":118},"01M71QD51HWSGYMCMB7RW7PGK8","vue-testing-best-practices","Use for Vue.js testing. Covers Vitest, Vue Test Utils, component testing, mocking, testing patterns, and Playwright for E2E testing.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-testing-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-testing-best-practices\u002FSKILL.md",[175,176],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},[178,102,179,165,180,113,181,182,183,160,184,104,185,186,187,137,188,166,189],"vue testing best practices","testing best practices","best practices","test","testing patterns","component","vitest","mocking","e2e","utils","patterns","e2e testing",{"skillNo":191,"name":192,"nameZh":6,"description":193,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":194,"sourceHtmlUrl":195,"categories":196,"keywords":198,"publishedAt":118},"01M71QD358H2DJ9THJRBP77T3T","vue-router-best-practices","Vue Router 4 patterns, navigation guards, route params, and route-component lifecycle interactions.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-router-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-router-best-practices\u002FSKILL.md",[197],{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},[199,165,200,180,201,183,202,160,188,203,204],"router","vue router best practices","route","guards","navigation","lifecycle",{"skillNo":206,"name":207,"nameZh":6,"description":208,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":209,"sourceHtmlUrl":210,"categories":211,"keywords":213,"publishedAt":118},"01M71QCYPNWDE2MQZ1TF3ED5S4","vue-best-practices","MUST be used for Vue.js tasks. Strongly recommends Composition API with `\u003Cscript setup>` and TypeScript as the standard approach. Covers Vue 3, SSR, Volar, vue-tsc. Load for any Vue, .vue files, Vue Router, Pinia, or Vite with Vue work. ALWAYS use Composition API unless the project explicitly requires Options API.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-best-practices\u002FSKILL.md",[212],{"categoryNo":98,"categoryName":99,"taxonomyType":21,"taxonomyTypeDesc":22},[214,165,180,215,157,216,217,218,199,219,220,221,222,223,224,104,225,137,226,227],"vue best practices","Composition","files","tasks","api","pinia","work","options","ssr","typescript","as","vite","load","standard"]