@codyswann/lisa 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +867 -0
- package/all/copy-overwrite/.claude/README.md +205 -0
- package/all/copy-overwrite/.claude/agents/agent-architect.md +311 -0
- package/all/copy-overwrite/.claude/agents/codebase-analyzer.md +146 -0
- package/all/copy-overwrite/.claude/agents/codebase-locator.md +125 -0
- package/all/copy-overwrite/.claude/agents/codebase-pattern-finder.md +237 -0
- package/all/copy-overwrite/.claude/agents/git-history-analyzer.md +183 -0
- package/all/copy-overwrite/.claude/agents/hooks-expert.md +74 -0
- package/all/copy-overwrite/.claude/agents/skill-evaluator.md +246 -0
- package/all/copy-overwrite/.claude/agents/slash-command-architect.md +87 -0
- package/all/copy-overwrite/.claude/agents/web-search-researcher.md +112 -0
- package/all/copy-overwrite/.claude/commands/git/commit-and-submit-pr.md +8 -0
- package/all/copy-overwrite/.claude/commands/git/commit.md +44 -0
- package/all/copy-overwrite/.claude/commands/git/prune.md +34 -0
- package/all/copy-overwrite/.claude/commands/git/submit-pr.md +50 -0
- package/all/copy-overwrite/.claude/commands/jira/create.md +50 -0
- package/all/copy-overwrite/.claude/commands/jira/verify.md +34 -0
- package/all/copy-overwrite/.claude/commands/project/archive.md +8 -0
- package/all/copy-overwrite/.claude/commands/project/bootstrap.md +49 -0
- package/all/copy-overwrite/.claude/commands/project/complete-task.md +7 -0
- package/all/copy-overwrite/.claude/commands/project/debrief.md +65 -0
- package/all/copy-overwrite/.claude/commands/project/execute.md +94 -0
- package/all/copy-overwrite/.claude/commands/project/implement.md +42 -0
- package/all/copy-overwrite/.claude/commands/project/local-code-review.md +88 -0
- package/all/copy-overwrite/.claude/commands/project/lower-code-complexity.md +74 -0
- package/all/copy-overwrite/.claude/commands/project/plan.md +314 -0
- package/all/copy-overwrite/.claude/commands/project/research.md +248 -0
- package/all/copy-overwrite/.claude/commands/project/review.md +63 -0
- package/all/copy-overwrite/.claude/commands/project/setup.md +19 -0
- package/all/copy-overwrite/.claude/commands/project/verify.md +38 -0
- package/all/copy-overwrite/.claude/commands/pull-request/review.md +12 -0
- package/all/copy-overwrite/.claude/commands/rules/format-md.md +72 -0
- package/all/copy-overwrite/.claude/commands/sonarqube/check.md +6 -0
- package/all/copy-overwrite/.claude/commands/sonarqube/fix.md +3 -0
- package/all/copy-overwrite/.claude/hooks/README.md +301 -0
- package/all/copy-overwrite/.claude/hooks/notify-ntfy.sh +181 -0
- package/all/copy-overwrite/.claude/settings.json +41 -0
- package/all/copy-overwrite/.claude/settings.local.json.example +14 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/SKILL.md +405 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/function-structure.md +416 -0
- package/all/copy-overwrite/.claude/skills/coding-philosophy/references/immutable-patterns.md +316 -0
- package/all/copy-overwrite/.claude/skills/prompt-complexity-scorer/SKILL.md +118 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/LICENSE.txt +202 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/SKILL.md +210 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/init_skill.py +303 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/all/copy-overwrite/.claude/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/all/copy-overwrite/CLAUDE.md +77 -0
- package/all/copy-overwrite/HUMAN.md +17 -0
- package/all/copy-overwrite/specs/.keep +0 -0
- package/all/create-only/PROJECT_RULES.md +0 -0
- package/cdk/merge/package.json +20 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +107 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts.d.ts +45 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +58 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/core/config.d.ts +73 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +36 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lisa.d.ts +81 -0
- package/dist/core/lisa.d.ts.map +1 -0
- package/dist/core/lisa.js +459 -0
- package/dist/core/lisa.js.map +1 -0
- package/dist/core/manifest.d.ts +58 -0
- package/dist/core/manifest.d.ts.map +1 -0
- package/dist/core/manifest.js +104 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/detection/detector.interface.d.ts +15 -0
- package/dist/detection/detector.interface.d.ts.map +1 -0
- package/dist/detection/detector.interface.js +2 -0
- package/dist/detection/detector.interface.js.map +1 -0
- package/dist/detection/detectors/cdk.d.ts +10 -0
- package/dist/detection/detectors/cdk.d.ts.map +1 -0
- package/dist/detection/detectors/cdk.js +34 -0
- package/dist/detection/detectors/cdk.js.map +1 -0
- package/dist/detection/detectors/expo.d.ts +10 -0
- package/dist/detection/detectors/expo.d.ts.map +1 -0
- package/dist/detection/detectors/expo.js +30 -0
- package/dist/detection/detectors/expo.js.map +1 -0
- package/dist/detection/detectors/nestjs.d.ts +10 -0
- package/dist/detection/detectors/nestjs.d.ts.map +1 -0
- package/dist/detection/detectors/nestjs.js +34 -0
- package/dist/detection/detectors/nestjs.js.map +1 -0
- package/dist/detection/detectors/npm-package.d.ts +13 -0
- package/dist/detection/detectors/npm-package.d.ts.map +1 -0
- package/dist/detection/detectors/npm-package.js +30 -0
- package/dist/detection/detectors/npm-package.js.map +1 -0
- package/dist/detection/detectors/typescript.d.ts +10 -0
- package/dist/detection/detectors/typescript.d.ts.map +1 -0
- package/dist/detection/detectors/typescript.js +25 -0
- package/dist/detection/detectors/typescript.js.map +1 -0
- package/dist/detection/index.d.ts +24 -0
- package/dist/detection/index.d.ts.map +1 -0
- package/dist/detection/index.js +57 -0
- package/dist/detection/index.js.map +1 -0
- package/dist/errors/index.d.ts +69 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +110 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/console-logger.d.ts +12 -0
- package/dist/logging/console-logger.d.ts.map +1 -0
- package/dist/logging/console-logger.js +22 -0
- package/dist/logging/console-logger.js.map +1 -0
- package/dist/logging/index.d.ts +4 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +3 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.interface.d.ts +20 -0
- package/dist/logging/logger.interface.d.ts.map +1 -0
- package/dist/logging/logger.interface.js +2 -0
- package/dist/logging/logger.interface.js.map +1 -0
- package/dist/logging/silent-logger.d.ts +12 -0
- package/dist/logging/silent-logger.d.ts.map +1 -0
- package/dist/logging/silent-logger.js +21 -0
- package/dist/logging/silent-logger.js.map +1 -0
- package/dist/strategies/copy-contents.d.ts +14 -0
- package/dist/strategies/copy-contents.d.ts.map +1 -0
- package/dist/strategies/copy-contents.js +69 -0
- package/dist/strategies/copy-contents.js.map +1 -0
- package/dist/strategies/copy-overwrite.d.ts +14 -0
- package/dist/strategies/copy-overwrite.d.ts.map +1 -0
- package/dist/strategies/copy-overwrite.js +47 -0
- package/dist/strategies/copy-overwrite.js.map +1 -0
- package/dist/strategies/create-only.d.ts +13 -0
- package/dist/strategies/create-only.d.ts.map +1 -0
- package/dist/strategies/create-only.js +30 -0
- package/dist/strategies/create-only.js.map +1 -0
- package/dist/strategies/index.d.ts +31 -0
- package/dist/strategies/index.d.ts.map +1 -0
- package/dist/strategies/index.js +52 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/strategies/merge.d.ts +13 -0
- package/dist/strategies/merge.d.ts.map +1 -0
- package/dist/strategies/merge.js +60 -0
- package/dist/strategies/merge.js.map +1 -0
- package/dist/strategies/strategy.interface.d.ts +31 -0
- package/dist/strategies/strategy.interface.d.ts.map +1 -0
- package/dist/strategies/strategy.interface.js +2 -0
- package/dist/strategies/strategy.interface.js.map +1 -0
- package/dist/transaction/backup.d.ts +38 -0
- package/dist/transaction/backup.d.ts.map +1 -0
- package/dist/transaction/backup.js +97 -0
- package/dist/transaction/backup.js.map +1 -0
- package/dist/transaction/index.d.ts +4 -0
- package/dist/transaction/index.d.ts.map +1 -0
- package/dist/transaction/index.js +3 -0
- package/dist/transaction/index.js.map +1 -0
- package/dist/transaction/transaction.d.ts +34 -0
- package/dist/transaction/transaction.d.ts.map +1 -0
- package/dist/transaction/transaction.js +68 -0
- package/dist/transaction/transaction.js.map +1 -0
- package/dist/utils/file-operations.d.ts +29 -0
- package/dist/utils/file-operations.d.ts.map +1 -0
- package/dist/utils/file-operations.js +84 -0
- package/dist/utils/file-operations.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/json-utils.d.ts +22 -0
- package/dist/utils/json-utils.d.ts.map +1 -0
- package/dist/utils/json-utils.js +57 -0
- package/dist/utils/json-utils.js.map +1 -0
- package/dist/utils/path-utils.d.ts +21 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/dist/utils/path-utils.js +35 -0
- package/dist/utils/path-utils.js.map +1 -0
- package/eslint-plugin-code-organization/README.md +149 -0
- package/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
- package/eslint-plugin-code-organization/index.js +23 -0
- package/eslint-plugin-code-organization/package.json +10 -0
- package/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
- package/expo/copy-overwrite/.claude/skills/apollo-client/SKILL.md +238 -0
- package/expo/copy-overwrite/.claude/skills/apollo-client/references/mutation-patterns.md +360 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/SKILL.md +360 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/atomic-levels.md +417 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/folder-structure.md +257 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/references/gluestack-mapping.md +233 -0
- package/expo/copy-overwrite/.claude/skills/atomic-design-gluestack/scripts/validate_atomic_structure.py +327 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/SKILL.md +299 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/examples.md +749 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/references/patterns.md +318 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/create_component.py +198 -0
- package/expo/copy-overwrite/.claude/skills/container-view-pattern/scripts/validate_component.py +207 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/SKILL.md +268 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/common-issues.md +619 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/file-extensions.md +340 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/references/platform-api.md +276 -0
- package/expo/copy-overwrite/.claude/skills/cross-platform-compatibility/scripts/validate_cross_platform.py +414 -0
- package/expo/copy-overwrite/.claude/skills/directory-structure/SKILL.md +202 -0
- package/expo/copy-overwrite/.claude/skills/directory-structure/scripts/validate_structure.py +443 -0
- package/expo/copy-overwrite/.claude/skills/expo-env-config/SKILL.md +309 -0
- package/expo/copy-overwrite/.claude/skills/expo-env-config/references/validation-patterns.md +417 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/SKILL.md +431 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/references/official-docs.md +290 -0
- package/expo/copy-overwrite/.claude/skills/expo-router-best-practices/scripts/generate-route.py +169 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/SKILL.md +411 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/color-tokens.md +343 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/component-mapping.md +307 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/references/spacing-scale.md +300 -0
- package/expo/copy-overwrite/.claude/skills/gluestack-nativewind/scripts/validate_styling.py +354 -0
- package/expo/copy-overwrite/.claude/skills/local-state/SKILL.md +362 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/async-storage.md +505 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/persistence-patterns.md +711 -0
- package/expo/copy-overwrite/.claude/skills/local-state/references/reactive-variables.md +446 -0
- package/expo/copy-overwrite/.claude/skills/playwright-selectors/SKILL.md +223 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/SKILL.md +319 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/async-patterns.md +420 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/expo-router-testing.md +556 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/mocking-patterns.md +590 -0
- package/expo/copy-overwrite/.claude/skills/testing-library/references/query-priority.md +291 -0
- package/expo/copy-overwrite/.easignore.extra +2 -0
- package/expo/copy-overwrite/.mcp.json +33 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/README.md +234 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/plugin-index.test.js +84 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/require-memo-in-view.test.js +196 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/__tests__/single-component-per-file.test.js +289 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/index.js +32 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/package.json +10 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/enforce-component-structure.js +230 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/no-return-in-view.js +91 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/require-memo-in-view.js +178 -0
- package/expo/copy-overwrite/eslint-plugin-component-structure/rules/single-component-per-file.js +238 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/README.md +260 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/index.js +29 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/package.json +10 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-classname-outside-ui.js +51 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-direct-rn-imports.js +55 -0
- package/expo/copy-overwrite/eslint-plugin-ui-standards/rules/no-inline-styles.js +73 -0
- package/expo/copy-overwrite/eslint.config.mjs +560 -0
- package/expo/copy-overwrite/lighthouserc.js +194 -0
- package/expo/create-only/lighthouserc-config.json +28 -0
- package/expo/merge/package.json +132 -0
- package/lisa.sh +35 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/SKILL.md +176 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/advanced-features.md +527 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/project-patterns.md +483 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/quick-start.md +257 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/resolvers-mutations.md +413 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-graphql/references/types-scalars.md +513 -0
- package/nestjs/copy-overwrite/.claude/skills/nestjs-rules/SKILL.md +536 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/SKILL.md +275 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/configuration-patterns.md +487 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/entity-patterns.md +450 -0
- package/nestjs/copy-overwrite/.claude/skills/typeorm-patterns/references/observability-patterns.md +536 -0
- package/nestjs/merge/package.json +75 -0
- package/package.json +124 -0
- package/typescript/copy-contents/.husky/commit-msg +91 -0
- package/typescript/copy-contents/.husky/pre-commit +96 -0
- package/typescript/copy-contents/.husky/pre-push +211 -0
- package/typescript/copy-overwrite/.claude/hooks/format-on-edit.sh +74 -0
- package/typescript/copy-overwrite/.claude/hooks/install_pkgs.sh +59 -0
- package/typescript/copy-overwrite/.claude/hooks/lint-on-edit.sh +103 -0
- package/typescript/copy-overwrite/.claude/skills/jsdoc-best-practices/SKILL.md +388 -0
- package/typescript/copy-overwrite/.github/README.md +455 -0
- package/typescript/copy-overwrite/.github/dependabot.yml +40 -0
- package/typescript/copy-overwrite/.github/k6/BROWSER_TESTING_NOTE.md +129 -0
- package/typescript/copy-overwrite/.github/k6/INTEGRATION_GUIDE.md +354 -0
- package/typescript/copy-overwrite/.github/k6/README.md +386 -0
- package/typescript/copy-overwrite/.github/k6/SCENARIO_SELECTION_GUIDE.md +264 -0
- package/typescript/copy-overwrite/.github/k6/examples/customer-deploy-integration.yml +115 -0
- package/typescript/copy-overwrite/.github/k6/examples/data-driven-test.js +268 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/load.js +142 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/load.json +27 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/smoke.js +26 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/smoke.json +20 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/soak.js +244 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/soak.json +29 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/spike.js +180 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/spike.json +32 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/stress.js +206 -0
- package/typescript/copy-overwrite/.github/k6/scenarios/stress.json +38 -0
- package/typescript/copy-overwrite/.github/k6/scripts/api-test.js +452 -0
- package/typescript/copy-overwrite/.github/k6/scripts/default-test.js +185 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/normal.json +30 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/relaxed.json +21 -0
- package/typescript/copy-overwrite/.github/k6/thresholds/strict.json +29 -0
- package/typescript/copy-overwrite/.github/workflows/build.yml +72 -0
- package/typescript/copy-overwrite/.github/workflows/ci.yml +49 -0
- package/typescript/copy-overwrite/.github/workflows/claude.yml +51 -0
- package/typescript/copy-overwrite/.github/workflows/create-github-issue-on-failure.yml +113 -0
- package/typescript/copy-overwrite/.github/workflows/create-jira-issue-on-failure.yml +195 -0
- package/typescript/copy-overwrite/.github/workflows/create-sentry-issue-on-failure.yml +267 -0
- package/typescript/copy-overwrite/.github/workflows/deploy.yml +228 -0
- package/typescript/copy-overwrite/.github/workflows/k6-load-test-README.md +230 -0
- package/typescript/copy-overwrite/.github/workflows/lighthouse.yml +68 -0
- package/typescript/copy-overwrite/.github/workflows/load-test.yml +282 -0
- package/typescript/copy-overwrite/.github/workflows/quality.yml +1737 -0
- package/typescript/copy-overwrite/.github/workflows/release.yml +1599 -0
- package/typescript/copy-overwrite/.gitleaksignore +28 -0
- package/typescript/copy-overwrite/.nvmrc +1 -0
- package/typescript/copy-overwrite/.prettierignore +23 -0
- package/typescript/copy-overwrite/.prettierrc.json +22 -0
- package/typescript/copy-overwrite/.versionrc +42 -0
- package/typescript/copy-overwrite/.yamllint +20 -0
- package/typescript/copy-overwrite/commitlint.config.js +11 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/README.md +149 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/__tests__/enforce-statement-order.test.js +468 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/index.js +23 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/package.json +10 -0
- package/typescript/copy-overwrite/eslint-plugin-code-organization/rules/enforce-statement-order.js +157 -0
- package/typescript/copy-overwrite/eslint.config.mjs +390 -0
- package/typescript/copy-overwrite/eslint.ignore.config.json +57 -0
- package/typescript/copy-overwrite/eslint.thresholds.config.json +5 -0
- package/typescript/github-rulesets/base.json +106 -0
- package/typescript/merge/.claude/settings.json +28 -0
- package/typescript/merge/package.json +71 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# K6 Load Testing Workflow
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `k6-load-test.yml` is a reusable GitHub Actions workflow designed to run k6 performance tests as part of your CI/CD pipeline. It supports multiple test scenarios, flexible configuration, and both local and cloud execution.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
name: Deploy and Test
|
|
11
|
+
on:
|
|
12
|
+
push:
|
|
13
|
+
branches: [main]
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
deploy:
|
|
17
|
+
# Your deployment steps
|
|
18
|
+
|
|
19
|
+
performance-test:
|
|
20
|
+
needs: deploy
|
|
21
|
+
uses: ./.github/workflows/k6-load-test.yml
|
|
22
|
+
with:
|
|
23
|
+
environment: production
|
|
24
|
+
test_scenario: smoke
|
|
25
|
+
base_url: https://api.example.com
|
|
26
|
+
secrets: inherit
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Workflow Inputs
|
|
30
|
+
|
|
31
|
+
| Input | Type | Required | Default | Description |
|
|
32
|
+
|-------|------|----------|---------|-------------|
|
|
33
|
+
| `environment` | string | Yes | - | Target environment (staging, production) |
|
|
34
|
+
| `test_scenario` | string | No | smoke | Test type: smoke, load, stress, spike, soak |
|
|
35
|
+
| `base_url` | string | Yes | - | Base URL of application to test |
|
|
36
|
+
| `k6_version` | string | No | latest | k6 version to use |
|
|
37
|
+
| `test_duration` | string | No | - | Override test duration (e.g., 5m, 1h) |
|
|
38
|
+
| `virtual_users` | number | No | - | Override number of virtual users |
|
|
39
|
+
| `thresholds_config` | string | No | - | Path to custom thresholds JSON |
|
|
40
|
+
| `test_script` | string | No | .github/k6/scripts/default-test.js | Path to k6 test script |
|
|
41
|
+
| `fail_on_threshold` | boolean | No | true | Fail workflow if thresholds not met |
|
|
42
|
+
| `upload_results` | boolean | No | true | Upload test results as artifacts |
|
|
43
|
+
| `cloud_run` | boolean | No | false | Run tests on k6 Cloud |
|
|
44
|
+
|
|
45
|
+
## Workflow Outputs
|
|
46
|
+
|
|
47
|
+
| Output | Description |
|
|
48
|
+
|--------|-------------|
|
|
49
|
+
| `test_passed` | Whether the test passed all thresholds (true/false) |
|
|
50
|
+
| `results_url` | URL to test results artifact |
|
|
51
|
+
| `summary` | Test execution summary |
|
|
52
|
+
|
|
53
|
+
## Workflow Secrets
|
|
54
|
+
|
|
55
|
+
| Secret | Required | Description |
|
|
56
|
+
|--------|----------|-------------|
|
|
57
|
+
| `K6_CLOUD_TOKEN` | No | k6 Cloud API token for cloud runs |
|
|
58
|
+
| `CUSTOM_HEADERS` | No | Custom headers for authenticated endpoints (JSON) |
|
|
59
|
+
|
|
60
|
+
## Test Scenarios
|
|
61
|
+
|
|
62
|
+
### Available Scenarios
|
|
63
|
+
|
|
64
|
+
- **smoke**: Quick validation (1 min, 1 VU)
|
|
65
|
+
- **load**: Normal traffic (9 min, 10 VUs)
|
|
66
|
+
- **stress**: Find breaking points (33 min, up to 200 VUs)
|
|
67
|
+
- **spike**: Sudden traffic changes (8 min, 5→100→5 VUs)
|
|
68
|
+
- **soak**: Extended duration (30+ min, 10 VUs)
|
|
69
|
+
|
|
70
|
+
### Selecting a Scenario
|
|
71
|
+
|
|
72
|
+
See the [Scenario Selection Guide](../k6/SCENARIO_SELECTION_GUIDE.md) for detailed guidance.
|
|
73
|
+
|
|
74
|
+
## Authentication
|
|
75
|
+
|
|
76
|
+
For testing protected endpoints:
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
uses: ./.github/workflows/k6-load-test.yml
|
|
80
|
+
with:
|
|
81
|
+
base_url: https://api.example.com
|
|
82
|
+
secrets:
|
|
83
|
+
CUSTOM_HEADERS: |
|
|
84
|
+
{
|
|
85
|
+
"Authorization": "Bearer ${{ secrets.API_TOKEN }}",
|
|
86
|
+
"X-API-Key": "${{ secrets.API_KEY }}"
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Custom Test Scripts
|
|
91
|
+
|
|
92
|
+
Use your own test script:
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
with:
|
|
96
|
+
test_script: .github/k6/scripts/my-custom-test.js
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Custom Thresholds
|
|
100
|
+
|
|
101
|
+
Use environment-specific thresholds:
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
with:
|
|
105
|
+
thresholds_config: .github/k6/thresholds/production.json
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## k6 Cloud Integration
|
|
109
|
+
|
|
110
|
+
For high-concurrency tests:
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
uses: ./.github/workflows/k6-load-test.yml
|
|
114
|
+
with:
|
|
115
|
+
cloud_run: true
|
|
116
|
+
secrets:
|
|
117
|
+
K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Artifacts
|
|
121
|
+
|
|
122
|
+
Test results are automatically uploaded as artifacts including:
|
|
123
|
+
- JSON results (`results.json`)
|
|
124
|
+
- CSV results (`results.csv`)
|
|
125
|
+
- HTML report (`report.html`)
|
|
126
|
+
- Scenario-specific summaries
|
|
127
|
+
|
|
128
|
+
Artifacts are retained for 30 days.
|
|
129
|
+
|
|
130
|
+
## Error Handling
|
|
131
|
+
|
|
132
|
+
The workflow handles various error scenarios:
|
|
133
|
+
- Base URL not accessible
|
|
134
|
+
- Test script not found
|
|
135
|
+
- Threshold failures
|
|
136
|
+
- k6 installation issues
|
|
137
|
+
|
|
138
|
+
See the [Troubleshooting Guide](../k6/INTEGRATION_GUIDE.md#troubleshooting) for solutions.
|
|
139
|
+
|
|
140
|
+
## Integration Patterns
|
|
141
|
+
|
|
142
|
+
For comprehensive integration examples, see the [Integration Guide](../k6/INTEGRATION_GUIDE.md).
|
|
143
|
+
|
|
144
|
+
### Integration with Release and Deployment Workflows
|
|
145
|
+
|
|
146
|
+
The k6 load testing workflow is designed to integrate seamlessly with your release and deployment processes. Here's the recommended pattern:
|
|
147
|
+
|
|
148
|
+
```yaml
|
|
149
|
+
# deploy.yml.example - Complete release and deployment with load testing
|
|
150
|
+
name: 🚀 Release and Deploy
|
|
151
|
+
|
|
152
|
+
on:
|
|
153
|
+
push:
|
|
154
|
+
branches: [main, staging, dev]
|
|
155
|
+
|
|
156
|
+
jobs:
|
|
157
|
+
# Step 1: Create a release
|
|
158
|
+
release:
|
|
159
|
+
uses: ./.github/workflows/release.yml
|
|
160
|
+
with:
|
|
161
|
+
environment: ${{ github.ref_name }}
|
|
162
|
+
# ... other inputs
|
|
163
|
+
|
|
164
|
+
# Step 2: Deploy to your infrastructure
|
|
165
|
+
deploy:
|
|
166
|
+
needs: release
|
|
167
|
+
runs-on: ubuntu-latest
|
|
168
|
+
outputs:
|
|
169
|
+
environment_url: ${{ steps.deploy.outputs.environment_url }}
|
|
170
|
+
steps:
|
|
171
|
+
# Your deployment logic here
|
|
172
|
+
|
|
173
|
+
# Step 3: Run load tests (staging only)
|
|
174
|
+
load_testing:
|
|
175
|
+
needs: [release, deploy]
|
|
176
|
+
if: |
|
|
177
|
+
needs.deploy.result == 'success' &&
|
|
178
|
+
github.ref_name == 'staging'
|
|
179
|
+
uses: ./.github/workflows/load-test.yml
|
|
180
|
+
with:
|
|
181
|
+
environment: staging
|
|
182
|
+
test_scenario: smoke
|
|
183
|
+
base_url: ${{ needs.deploy.outputs.environment_url }}
|
|
184
|
+
fail_on_threshold: false # Don't fail the deployment
|
|
185
|
+
secrets: inherit
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
This pattern ensures:
|
|
189
|
+
- Releases are created first with proper versioning
|
|
190
|
+
- Deployments happen after successful releases
|
|
191
|
+
- Load tests run automatically for staging deployments
|
|
192
|
+
- Production deployments skip load testing (run manually if needed)
|
|
193
|
+
|
|
194
|
+
## File Structure
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
.github/
|
|
198
|
+
├── workflows/
|
|
199
|
+
│ └── k6-load-test.yml # This workflow
|
|
200
|
+
└── k6/
|
|
201
|
+
├── scripts/ # Test scripts
|
|
202
|
+
├── scenarios/ # Scenario configs
|
|
203
|
+
├── thresholds/ # Threshold configs
|
|
204
|
+
└── examples/ # Usage examples
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Workflow Steps
|
|
208
|
+
|
|
209
|
+
1. **Checkout**: Get repository code
|
|
210
|
+
2. **Setup k6**: Install specified k6 version
|
|
211
|
+
3. **Prepare Environment**: Set up test variables
|
|
212
|
+
4. **Run Test**: Execute k6 with parameters
|
|
213
|
+
5. **Generate Summary**: Create test report
|
|
214
|
+
6. **Upload Results**: Store artifacts
|
|
215
|
+
7. **Comment on PR**: Add results to PR (if applicable)
|
|
216
|
+
|
|
217
|
+
## Best Practices
|
|
218
|
+
|
|
219
|
+
1. Start with smoke tests
|
|
220
|
+
2. Use appropriate scenarios per environment
|
|
221
|
+
3. Set realistic thresholds
|
|
222
|
+
4. Monitor resource usage during tests
|
|
223
|
+
5. Review results regularly
|
|
224
|
+
6. Update tests as application evolves
|
|
225
|
+
|
|
226
|
+
## Support
|
|
227
|
+
|
|
228
|
+
- [k6 Documentation](https://k6.io/docs/)
|
|
229
|
+
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
|
230
|
+
- Project-specific guides in `.github/k6/`
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: 💡 Lighthouse CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
node_version:
|
|
7
|
+
description: 'Node.js version to use'
|
|
8
|
+
required: false
|
|
9
|
+
default: '20.x'
|
|
10
|
+
type: string
|
|
11
|
+
package_manager:
|
|
12
|
+
description: 'Package manager to use (npm, yarn, or bun)'
|
|
13
|
+
required: false
|
|
14
|
+
default: 'yarn'
|
|
15
|
+
type: string
|
|
16
|
+
target_branch:
|
|
17
|
+
description: 'Target branch for the PR (used to determine environment)'
|
|
18
|
+
required: false
|
|
19
|
+
default: 'staging'
|
|
20
|
+
type: string
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
lighthouse:
|
|
24
|
+
name: 💡 Performance Budget Check
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 15
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: 📥 Checkout repository
|
|
30
|
+
uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- name: 🔧 Setup Node.js
|
|
33
|
+
uses: actions/setup-node@v4
|
|
34
|
+
with:
|
|
35
|
+
node-version: ${{ inputs.node_version }}
|
|
36
|
+
cache: ${{ inputs.package_manager != 'bun' && inputs.package_manager || '' }}
|
|
37
|
+
|
|
38
|
+
- name: 🍞 Setup Bun
|
|
39
|
+
if: inputs.package_manager == 'bun'
|
|
40
|
+
uses: oven-sh/setup-bun@v2
|
|
41
|
+
with:
|
|
42
|
+
bun-version: latest
|
|
43
|
+
|
|
44
|
+
- name: 📦 Install dependencies
|
|
45
|
+
run: |
|
|
46
|
+
if [ "${{ inputs.package_manager }}" = "npm" ]; then
|
|
47
|
+
npm ci
|
|
48
|
+
elif [ "${{ inputs.package_manager }}" = "yarn" ]; then
|
|
49
|
+
yarn install --frozen-lockfile
|
|
50
|
+
elif [ "${{ inputs.package_manager }}" = "bun" ]; then
|
|
51
|
+
bun install --frozen-lockfile
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
- name: 🏗️ Build web export
|
|
55
|
+
run: ${{ inputs.package_manager }} run export:web
|
|
56
|
+
env:
|
|
57
|
+
TARGET_BRANCH: ${{ inputs.target_branch }}
|
|
58
|
+
|
|
59
|
+
- name: 💡 Run Lighthouse CI
|
|
60
|
+
run: ${{ inputs.package_manager }} run lighthouse:check
|
|
61
|
+
|
|
62
|
+
- name: 📊 Upload Lighthouse reports
|
|
63
|
+
uses: actions/upload-artifact@v4
|
|
64
|
+
if: always()
|
|
65
|
+
with:
|
|
66
|
+
name: lighthouse-reports
|
|
67
|
+
path: .lighthouseci/
|
|
68
|
+
retention-days: 30
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
name: K6 Load Testing
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
environment:
|
|
7
|
+
description: 'Target environment to test'
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
test_scenario:
|
|
11
|
+
description: 'Test scenario to run (smoke, load, stress, spike, soak)'
|
|
12
|
+
required: false
|
|
13
|
+
type: string
|
|
14
|
+
default: 'smoke'
|
|
15
|
+
base_url:
|
|
16
|
+
description: 'Base URL of the application to test'
|
|
17
|
+
required: true
|
|
18
|
+
type: string
|
|
19
|
+
k6_version:
|
|
20
|
+
description: 'k6 version to use'
|
|
21
|
+
required: false
|
|
22
|
+
type: string
|
|
23
|
+
default: 'latest'
|
|
24
|
+
test_duration:
|
|
25
|
+
description: 'Override test duration (e.g., 5m, 1h)'
|
|
26
|
+
required: false
|
|
27
|
+
type: string
|
|
28
|
+
virtual_users:
|
|
29
|
+
description: 'Override number of virtual users'
|
|
30
|
+
required: false
|
|
31
|
+
type: number
|
|
32
|
+
thresholds_config:
|
|
33
|
+
description: 'Path to custom thresholds configuration'
|
|
34
|
+
required: false
|
|
35
|
+
type: string
|
|
36
|
+
test_script:
|
|
37
|
+
description: 'Path to custom k6 test script'
|
|
38
|
+
required: false
|
|
39
|
+
type: string
|
|
40
|
+
default: '.github/k6/scripts/default-test.js'
|
|
41
|
+
fail_on_threshold:
|
|
42
|
+
description: 'Fail workflow if thresholds are not met'
|
|
43
|
+
required: false
|
|
44
|
+
type: boolean
|
|
45
|
+
default: true
|
|
46
|
+
upload_results:
|
|
47
|
+
description: 'Upload test results as artifacts'
|
|
48
|
+
required: false
|
|
49
|
+
type: boolean
|
|
50
|
+
default: true
|
|
51
|
+
cloud_run:
|
|
52
|
+
description: 'Run tests on k6 Cloud (requires K6_CLOUD_TOKEN secret)'
|
|
53
|
+
required: false
|
|
54
|
+
type: boolean
|
|
55
|
+
default: false
|
|
56
|
+
outputs:
|
|
57
|
+
test_passed:
|
|
58
|
+
description: 'Whether the test passed all thresholds'
|
|
59
|
+
value: ${{ jobs.k6_test.outputs.passed }}
|
|
60
|
+
results_url:
|
|
61
|
+
description: 'URL to test results (if uploaded)'
|
|
62
|
+
value: ${{ jobs.k6_test.outputs.results_url }}
|
|
63
|
+
summary:
|
|
64
|
+
description: 'Test execution summary'
|
|
65
|
+
value: ${{ jobs.k6_test.outputs.summary }}
|
|
66
|
+
secrets:
|
|
67
|
+
K6_CLOUD_TOKEN:
|
|
68
|
+
required: false
|
|
69
|
+
description: 'k6 Cloud API token for cloud runs'
|
|
70
|
+
CUSTOM_HEADERS:
|
|
71
|
+
required: false
|
|
72
|
+
description: 'Custom headers for authenticated endpoints (JSON format)'
|
|
73
|
+
|
|
74
|
+
jobs:
|
|
75
|
+
k6_test:
|
|
76
|
+
name: K6 Load Test - ${{ inputs.test_scenario }}
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
outputs:
|
|
79
|
+
passed: ${{ steps.run_test.outputs.passed }}
|
|
80
|
+
results_url: ${{ steps.upload_results.outputs.artifact-url }}
|
|
81
|
+
summary: ${{ steps.generate_summary.outputs.summary }}
|
|
82
|
+
|
|
83
|
+
steps:
|
|
84
|
+
- name: Checkout repository
|
|
85
|
+
uses: actions/checkout@v4
|
|
86
|
+
|
|
87
|
+
- name: Set up k6
|
|
88
|
+
run: |
|
|
89
|
+
if [ "${{ inputs.k6_version }}" = "latest" ]; then
|
|
90
|
+
sudo gpg -k
|
|
91
|
+
sudo gpg --no-default-keyring \
|
|
92
|
+
--keyring /usr/share/keyrings/k6-archive-keyring.gpg \
|
|
93
|
+
--keyserver hkp://keyserver.ubuntu.com:80 \
|
|
94
|
+
--recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
|
|
95
|
+
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
|
|
96
|
+
| sudo tee /etc/apt/sources.list.d/k6.list
|
|
97
|
+
sudo apt-get update
|
|
98
|
+
sudo apt-get install k6
|
|
99
|
+
else
|
|
100
|
+
K6_VERSION="${{ inputs.k6_version }}"
|
|
101
|
+
wget "https://github.com/grafana/k6/releases/download/v${K6_VERSION}/k6-v${K6_VERSION}-linux-amd64.tar.gz"
|
|
102
|
+
tar -xzf "k6-v${K6_VERSION}-linux-amd64.tar.gz"
|
|
103
|
+
sudo mv "k6-v${K6_VERSION}-linux-amd64/k6" /usr/local/bin/
|
|
104
|
+
fi
|
|
105
|
+
k6 version
|
|
106
|
+
|
|
107
|
+
- name: Prepare test environment
|
|
108
|
+
id: prepare_test
|
|
109
|
+
run: |
|
|
110
|
+
# Create results directory
|
|
111
|
+
mkdir -p k6-results
|
|
112
|
+
|
|
113
|
+
# Export environment variables for k6
|
|
114
|
+
{
|
|
115
|
+
echo "K6_BASE_URL=${{ inputs.base_url }}"
|
|
116
|
+
echo "K6_SCENARIO=${{ inputs.test_scenario }}"
|
|
117
|
+
echo "K6_ENVIRONMENT=${{ inputs.environment }}"
|
|
118
|
+
} >> "$GITHUB_ENV"
|
|
119
|
+
|
|
120
|
+
# Set custom duration if provided
|
|
121
|
+
if [ -n "${{ inputs.test_duration }}" ]; then
|
|
122
|
+
echo "K6_DURATION=${{ inputs.test_duration }}" >> "$GITHUB_ENV"
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
# Set custom VUs if provided
|
|
126
|
+
if [ -n "${{ inputs.virtual_users }}" ]; then
|
|
127
|
+
echo "K6_VUS=${{ inputs.virtual_users }}" >> "$GITHUB_ENV"
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
# Set custom headers if provided
|
|
131
|
+
if [ -n "${{ secrets.CUSTOM_HEADERS }}" ]; then
|
|
132
|
+
echo "K6_CUSTOM_HEADERS=${{ secrets.CUSTOM_HEADERS }}" >> "$GITHUB_ENV"
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# Set cloud token if cloud run is enabled
|
|
136
|
+
if [ "${{ inputs.cloud_run }}" = "true" ] && [ -n "${{ secrets.K6_CLOUD_TOKEN }}" ]; then
|
|
137
|
+
echo "K6_CLOUD_TOKEN=${{ secrets.K6_CLOUD_TOKEN }}" >> "$GITHUB_ENV"
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
- name: Run k6 test
|
|
141
|
+
id: run_test
|
|
142
|
+
run: |
|
|
143
|
+
set +e # Don't exit immediately on error
|
|
144
|
+
|
|
145
|
+
# Use the shared runner script if a scenario is specified, otherwise use custom script
|
|
146
|
+
if [ "${{ inputs.test_script }}" = ".github/k6/scripts/default-test.js" ]; then
|
|
147
|
+
# Use shared runner for standard scenarios
|
|
148
|
+
RUNNER_ARGS="--scenario ${{ inputs.test_scenario }} --url ${{ inputs.base_url }} --json --csv"
|
|
149
|
+
|
|
150
|
+
# Add cloud option if enabled
|
|
151
|
+
if [ "${{ inputs.cloud_run }}" = "true" ]; then
|
|
152
|
+
RUNNER_ARGS="$RUNNER_ARGS --cloud"
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
# Add duration override if provided
|
|
156
|
+
if [ -n "${{ inputs.test_duration }}" ]; then
|
|
157
|
+
RUNNER_ARGS="$RUNNER_ARGS --duration ${{ inputs.test_duration }}"
|
|
158
|
+
fi
|
|
159
|
+
|
|
160
|
+
# Add VUs override if provided
|
|
161
|
+
if [ -n "${{ inputs.virtual_users }}" ]; then
|
|
162
|
+
RUNNER_ARGS="$RUNNER_ARGS --vus ${{ inputs.virtual_users }}"
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# Add no-thresholds flag if needed
|
|
166
|
+
if [ "${{ inputs.fail_on_threshold }}" != "true" ]; then
|
|
167
|
+
RUNNER_ARGS="$RUNNER_ARGS --no-thresholds"
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
echo "Running shared k6 runner: ./scripts/k6-run.sh $RUNNER_ARGS"
|
|
171
|
+
./scripts/k6-run.sh $RUNNER_ARGS
|
|
172
|
+
TEST_EXIT_CODE=$?
|
|
173
|
+
else
|
|
174
|
+
# Use custom script directly with k6
|
|
175
|
+
TEST_SCRIPT="${{ inputs.test_script }}"
|
|
176
|
+
|
|
177
|
+
# Build k6 command
|
|
178
|
+
K6_CMD="k6 run"
|
|
179
|
+
|
|
180
|
+
# Add cloud option if enabled
|
|
181
|
+
if [ "${{ inputs.cloud_run }}" = "true" ]; then
|
|
182
|
+
K6_CMD="$K6_CMD --cloud"
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
# Add output options for local runs
|
|
186
|
+
if [ "${{ inputs.cloud_run }}" != "true" ]; then
|
|
187
|
+
K6_CMD="$K6_CMD --out json=k6-results/results.json --out csv=k6-results/results.csv"
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
# Add thresholds config if provided
|
|
191
|
+
if [ -n "${{ inputs.thresholds_config }}" ]; then
|
|
192
|
+
K6_CMD="$K6_CMD --config ${{ inputs.thresholds_config }}"
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
# Add test script
|
|
196
|
+
K6_CMD="$K6_CMD $TEST_SCRIPT"
|
|
197
|
+
|
|
198
|
+
echo "Running k6 command: $K6_CMD"
|
|
199
|
+
$K6_CMD
|
|
200
|
+
TEST_EXIT_CODE=$?
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
echo "exit_code=$TEST_EXIT_CODE" >> "$GITHUB_OUTPUT"
|
|
204
|
+
|
|
205
|
+
# Determine if test passed
|
|
206
|
+
if [ $TEST_EXIT_CODE -eq 0 ]; then
|
|
207
|
+
echo "passed=true" >> "$GITHUB_OUTPUT"
|
|
208
|
+
echo "✅ Test passed all thresholds" >> "$GITHUB_STEP_SUMMARY"
|
|
209
|
+
else
|
|
210
|
+
echo "passed=false" >> "$GITHUB_OUTPUT"
|
|
211
|
+
echo "❌ Test failed thresholds" >> "$GITHUB_STEP_SUMMARY"
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
# Exit with appropriate code based on fail_on_threshold setting
|
|
215
|
+
if [ "${{ inputs.fail_on_threshold }}" = "true" ] && [ $TEST_EXIT_CODE -ne 0 ]; then
|
|
216
|
+
exit $TEST_EXIT_CODE
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
- name: Generate test summary
|
|
220
|
+
id: generate_summary
|
|
221
|
+
if: always()
|
|
222
|
+
run: |
|
|
223
|
+
# Create summary content
|
|
224
|
+
SUMMARY="# K6 Load Test Results\n\n"
|
|
225
|
+
SUMMARY+="**Environment:** ${{ inputs.environment }}\n"
|
|
226
|
+
SUMMARY+="**Test Scenario:** ${{ inputs.test_scenario }}\n"
|
|
227
|
+
SUMMARY+="**Base URL:** ${{ inputs.base_url }}\n"
|
|
228
|
+
SUMMARY+="**Test Status:** "
|
|
229
|
+
|
|
230
|
+
if [ "${{ steps.run_test.outputs.passed }}" = "true" ]; then
|
|
231
|
+
SUMMARY+="✅ PASSED\n"
|
|
232
|
+
else
|
|
233
|
+
SUMMARY+="❌ FAILED\n"
|
|
234
|
+
fi
|
|
235
|
+
|
|
236
|
+
# Add summary to GitHub Step Summary
|
|
237
|
+
echo -e "$SUMMARY" >> "$GITHUB_STEP_SUMMARY"
|
|
238
|
+
|
|
239
|
+
# Extract key metrics from results if available
|
|
240
|
+
if [ -f "k6-results/results.json" ]; then
|
|
241
|
+
echo -e "\n## Key Metrics\n" >> "$GITHUB_STEP_SUMMARY"
|
|
242
|
+
|
|
243
|
+
# Parse JSON results for key metrics (simplified example)
|
|
244
|
+
# In a real implementation, you'd use jq or similar to extract detailed metrics
|
|
245
|
+
echo "📊 Detailed metrics available in artifacts" >> "$GITHUB_STEP_SUMMARY"
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
# Output summary for workflow output
|
|
249
|
+
{
|
|
250
|
+
echo "summary<<EOF"
|
|
251
|
+
echo -e "$SUMMARY"
|
|
252
|
+
echo "EOF"
|
|
253
|
+
} >> "$GITHUB_OUTPUT"
|
|
254
|
+
|
|
255
|
+
- name: Upload test results
|
|
256
|
+
id: upload_results
|
|
257
|
+
if: always() && inputs.upload_results
|
|
258
|
+
uses: actions/upload-artifact@v4
|
|
259
|
+
with:
|
|
260
|
+
name: k6-results-${{ inputs.environment }}-${{ inputs.test_scenario }}-${{ github.run_id }}
|
|
261
|
+
path: k6-results/
|
|
262
|
+
retention-days: 30
|
|
263
|
+
|
|
264
|
+
- name: Comment on PR
|
|
265
|
+
if: github.event_name == 'pull_request' && always()
|
|
266
|
+
uses: actions/github-script@v7
|
|
267
|
+
with:
|
|
268
|
+
script: |
|
|
269
|
+
const summary = `${{ steps.generate_summary.outputs.summary }}`;
|
|
270
|
+
const resultsUrl = '${{ steps.upload_results.outputs.artifact-url }}';
|
|
271
|
+
|
|
272
|
+
let comment = summary;
|
|
273
|
+
if (resultsUrl) {
|
|
274
|
+
comment += `\n\n[📊 View detailed results](${resultsUrl})`;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
github.rest.issues.createComment({
|
|
278
|
+
issue_number: context.issue.number,
|
|
279
|
+
owner: context.repo.owner,
|
|
280
|
+
repo: context.repo.repo,
|
|
281
|
+
body: comment
|
|
282
|
+
});
|