From 7fe5291857fcc9f56fd706a4635064d01a8c5f0f Mon Sep 17 00:00:00 2001 From: Ebony Louis Date: Mon, 30 Jun 2025 17:07:25 -0400 Subject: [PATCH 1/2] add internal recipes --- .../analyze-java-monorepo-failures.yaml | 147 +++++++++++++++ .../recipes/data/recipes/analyze-pr.yaml | 57 ++++++ .../recipes/blokker-snapshot-migrator.yaml | 171 ++++++++++++++++++ .../recipes/data/recipes/change-log.yaml | 74 ++++++++ .../data/recipes/create-kafka-topic.yaml | 54 ++++++ .../data/recipes/dev-guide-migration.yaml | 45 +++++ .../data/recipes/fix-pr-ci-failures.yaml | 81 +++++++++ .../migrate-cypress-test-to-playwright.yaml | 65 +++++++ .../recipes/migrate-from-poetry-to-uv.yaml | 28 +++ .../recipes/data/recipes/pr-demo-planner.yaml | 64 +++++++ .../recipes/data/recipes/readme-bot.yaml | 35 ++++ .../data/recipes/recipe-generator.yaml | 49 +++++ .../remove-ai-artifacts-from-python-code.yaml | 37 ++++ documentation/src/pages/recipes/index.tsx | 2 +- 14 files changed, 908 insertions(+), 1 deletion(-) create mode 100644 documentation/src/pages/recipes/data/recipes/analyze-java-monorepo-failures.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/analyze-pr.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/blokker-snapshot-migrator.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/change-log.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/create-kafka-topic.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/dev-guide-migration.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/fix-pr-ci-failures.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/migrate-cypress-test-to-playwright.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/migrate-from-poetry-to-uv.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/pr-demo-planner.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/readme-bot.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/recipe-generator.yaml create mode 100644 documentation/src/pages/recipes/data/recipes/remove-ai-artifacts-from-python-code.yaml diff --git a/documentation/src/pages/recipes/data/recipes/analyze-java-monorepo-failures.yaml b/documentation/src/pages/recipes/data/recipes/analyze-java-monorepo-failures.yaml new file mode 100644 index 000000000000..02c8b25f647d --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/analyze-java-monorepo-failures.yaml @@ -0,0 +1,147 @@ +version: 1.0.0 +title: Analyze java monorepo build failure +description: Analyze java monorepo build failure +instructions: follow the prompts to analyze java monorepo build failure +activities: + - Fetch failed build parts + - Download and parse logs + - Identify root causes + - Analyze test failures + - Summarize common issues and next steps + - Generate HTML report +prompt: | + Guidelines: + - Use curl instead of browser-based extensions like fetch. + - Use jq for JSON parsing and transformations. + - Prefer creating reusable shell functions for repeated steps. + - **Do NOT** make up any information, only use the information provided in the logs. + + Step 1: Fetch Failed Build Parts + - run the command + ``` + curl https://kochiku.sqprod.co/squareup/java/builds/{{build_id}}?format=json \ + | jq '[.build.build_parts[] | select(.status == "failed") \ + | {id, build_id, kind, attempt_count, status}]' > failed_builds.json + ``` + + Step 2: + For each failed build part, create a loop to handle each part: + 2.1 Fetch the last attempt + - find the last attempt via curl https://kochiku.sqprod.co/squareup/java/builds/{build_id}/parts/{id}?format=json | jq '.build_part.build_attempts[-1]' + 2.2 fetch the stdout.log.gz and junit-report.html (if present) + - get artifact_id of the log files including stdout.log.gz and junit-report.html (if present) in the last attempt + Example of json + { + "build_part": { + "id": 841284189, + "build_id": 9937415, + "kind": "deployable-loan-gateway", + "paths": [ + "loan-gateway:test" + ], + "status": "failed", + "elapsed_time": 812, + "build_attempts": [ + { + "id": 612181475, + "build_part_id": 841284189, + "files": [ + { + "build_artifact": { + "id": 2125669387, + "build_attempt_id": 612181475, + "created_at": "2025-05-02T15:01:19.000-07:00", + "updated_at": "2025-05-02T15:01:19.000-07:00", + "log_file": { + "url": "/build_artifacts/2125669387", + "name": "squareup/java/build_9937415/part_841284189/attempt_612181475/stdout.log.gz" + } + } + } + ] + } + ] + } + } + - construct the artifact_url https://kochiku.sqprod.co/build_artifacts/{artifact_id} + - add the part_url, stdout.log artifact_url and junit_report url in the failed_builds.json in the matching build_part block. If the file does not exist, set the field to null + 2.3 Analyze the stdout.log.gz file + - download stdout.log.gz file using curl command with follow redirect option + - find the error in this file error keywords of "error,failed,fails,fail,fatal"(case insensitive), and also include the 2 lines before and 10 lines after the found error, saved the result into a file with filtered_error_{artifact_id}.txt + - add the filtered_error_{artifact_id}.txt file name to the corresponding build part in failed_builds.json + 2.4 Root Cause Analysis for Filtered Error + - review filtered_error_{artifact_id}.txt + - Determine the root cause of the error + - Provide + 1. Root cause + - Provide a comprehensive explanation of why the failure occurred. + - Explain the specific failure context (e.g., what phase failed — dependency resolution, test execution, compilation, etc.). + - Mention any recent changes (code, dependencies, infra) if visible or likely from logs. + 2. Detailed Justifications: + - Quote the relevant error messages or stack traces verbatim from the logs. + - Describe what each error message means, what tool/component is involved (e.g., Maven, Gradle, JUnit, Kotlin compiler, etc.), and how it relates to the build. + - Provide background context — e.g., "This type of error is common when ..." or "Historically, this happens when ..." + - Discuss any patterns observed across multiple failed parts with similar symptoms. + 3. Suggestions for Fixing the Problem: + - Propose practical and actionable fixes. + - Suggest specific files or lines that may need changes (e.g., build.gradle, test class). + - If applicable, recommend mitigations (e.g., retry the build, invalidate caches, contact a service owner). + - For flaky tests or environmental issues, suggest diagnostics (e.g., re-run in isolation, check recent infra changes). + - Add this analysis (root cause, justification, and suggestions) to the relevant build part in failed_builds.json. + 2.5 Check for Test Failures + - If the stdout.log.gz file contains "tests_result=3", it indicates some tests failed in this build + - download junit-report.html use curl command (if available) with follow redirect option + - Parse the HTML to extract: + - Names of failed test classes and methods. + - Associated error messages or stack traces. + - save this information to filtered_test_error_{artifact_id}.html + 2.6 Root Cause Analysis for Test Failures + - review filtered_test_error_{artifact_id}.html + - Determine the root cause of the test failures + - Provide + 1. Root cause + - Explain why the test failed, including what condition, assertion, or runtime behavior caused it. + - Identify whether the issue is likely caused by a code regression, incorrect test setup, flaky behavior, environment issues, or external dependencies (e.g., services, databases). + - Mention if multiple test failures appear to share a root cause (e.g., shared fixture or mock failure). + 2. Detailed Justifications: + - Quote the exact test name (class and method), along with failure messages or stack traces. + - Explain what the test was trying to validate, and what part of the system it targets (e.g., business logic, edge case, error handling). + - Provide background: has this test failed before? Is it marked flaky or is the logic fragile? + - If applicable, explain why this issue might only occur in CI (e.g., timing, parallelism, test order). + 3. Suggestions for Fixing the Problem + - Suggested for fixing the problem + - add the root cause analysis, detailed justifications and potential fix suggestions to the matching build part in the `failed_builds.json` + + Step 3: Verify Completeness + - Verify each build part in failed_builds.json have been analyzed. + - If any of the build part has not been verified, repeat Step 2 for these build part + + Step 4: + - Review all build part analyses. + - Identify recurring root causes and classify them as common issues. + - Suggest immediate next steps that apply across multiple build parts (e.g., restarting a flaky test, checking dependency versions). + - Add a common_issues field and an immediate_next_steps field to the failed_builds.json file. + Step 5: + - Using the completed failed_builds.json, create a readable HTML report named: java_monorepo_build_analysis_{build_id}.html + - The HTML report should include: + - A list of issues (common issues are grouped together) + For each issue, list: + - The associated build parts and part urls + - Links to stdout.log.gz and junit-report.html. + - Root cause + - Justifications + - Fix suggestions + - Immediate next steps for fixing the issues. +extensions: +- type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true +parameters: +- key: build_id + input_type: number + requirement: user_prompt + description: the failed build id to analyze +author: + contact: lifeizhou-ap \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/analyze-pr.yaml b/documentation/src/pages/recipes/data/recipes/analyze-pr.yaml new file mode 100644 index 000000000000..f38c44b6bbd1 --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/analyze-pr.yaml @@ -0,0 +1,57 @@ +id: analyze-pr +version: 1.0.0 +title: Analyse PR +author: + contact: douwe +description: Analyse a pr +instructions: Your job is to analyse and explain a PR +activities: + - Query authentication logs + - Investigate Sentry reports + - Correlate device usage with auth events + - Query Snowflake user identity tables + - Review repo code for auth issues +parameters: + - key: pr + input_type: string + requirement: required + description: name of the pull request + - key: repo + input_type: string + requirement: optional + description: name of the repo. uses the current one if not selected + default: "" +extensions: + - type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true + - type: builtin + name: memory + display_name: Memory + timeout: 300 + bundled: true + description: "For storing and retrieving formating preferences that might be present" +prompt: | + Analyze the pr with the name {{ pr }}. Find out what has changed, try to figure out why these + changes were made and tell the user in detail what you found out. + {% if repo %} + We are working with the {{ repo }} repository, so make sure to add that to all commands. + {% endif %} + + Steps: + 1. Find the actual pull request. {{ pr }} is the name or part of it. You can just run + `gh pr list` + and see which prs are open. Note which one the user is talking about + 2. Look at what is changed. You can run: + `gh pr view --comments --commits --files` + to get an overview. + 3. Optionally: if this looks complicated you could check out the relevant commit and have + a look at the files involved to get more context. If you do this, mark which branch you + were on. If there are pending changes, do a git stash + 4. Gather your thoughts and tell the user what changed, which changes look like they might + be worth an extra look and give them an idea of maybe why these changes were needed + 5. Clean up after yourself. If you cloned a repository or checked out a commit, make sure + you return the state to what it was before. So if in step 3 you changed branch, change + it back. If you had git stashed something, stash pop it again. \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/blokker-snapshot-migrator.yaml b/documentation/src/pages/recipes/data/recipes/blokker-snapshot-migrator.yaml new file mode 100644 index 000000000000..d9068f774e69 --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/blokker-snapshot-migrator.yaml @@ -0,0 +1,171 @@ +version: 1.0.0 +title: Blokker Snapshot Migrator +author: + contact: jadam +description: Migrate to Snapshot Testing for FormBlockers +instructions: Follow the prompts to migrate a service to snapshot testing +activities: + - Create a migration branch + - Add plasma-testing dependency to Gradle config + - Identify usages of FormBlocker.Builder() + - Locate and update associated test classes + - Commit test and snapshot changes + - Create and submit a pull request +extensions: +- type: builtin + name: developer + display_name: Developer + timeout: 600 + bundled: true +prompt: | + # Pre-Instructions + + ## Working Directory + - No files outside the directory {{working_directory}} should be modified. + - No commands should be run outside of the directory {{working_directory}}. + + ## Gradle + - To run gradle, use `bin/gradle ` from the project root. There is NO `gradlew` script. + - If you are working in cash-server, the repository consists of many projects. You should usually specify a specific project with `-p` any time you are calling gradle from the root directory. The gradle to use is located at `cash-server/bin/gradle` even if you're in a subproject. + + # Instructions + Perform the following steps to migrate to snapshot testing: + + 1. Create a new branch and check it out for the migration using the following command: + + ```bash + git checkout -b $USER/$(date +%m%d%Y)-formblocker-snapshot-migration + ```` + + 2. Ensure that the `plasma-testing` library is added to the `gradle/libs.versions.toml` file. If it is not, add it: + + ```toml + [libraries] + plasmaTesting = { module = "com.squareup.plasma:plasma-testing", version = "2025.04.01-1743540086-eeb2f79" } + ``` + + 3. Find all files that FormBlocker.Builder() is used in. + + 4. Locate the associated test classes. These are the files to update. + + 5. Update the `build.gradle.kts` files of the modules that contain the test classes to include the following dependencies: + + If `cash-server` is not in the current path: + ```kotlin + dependencies { + testImplementation(libs.plasmaTesting) + } + ``` + + If `cash-server` is in the current path: + ```kotlin + dependencies { + testImplementation(project(":plasma:plasma-testing")) + } + ``` + + 6. Update any test methods from these classes that test the outputs of a FormBlocker.Builder() to use the BlockerTester.snapshot() method. + + Make sure that any modified test files have the import `import com.squareup.cash.blockertesting.BlockerTester`. + + Examples: + ```kotlin + import com.squareup.cash.blockertesting.BlockerTester + + class SomeBlockerTest { + @Inject private lateinit var requirementHandler: SomeRequirementHandler + + @Test + fun testManual() { + // Test some blocker you built by hand. + // This isn't useful in practice, but it's simple and illustrative + val blocker = FormBlocker.Builder().elements(listOf(text("Sample"))).build() + BlockerTester.snapshot("SNAPSHOT_NAME", blocker) + } + + @Test + fun testHandler() { + // Test a blocker you get back from calling a Plasma FlowHandler or RequirementHandler + val response = requirementHandler.plan(request) + val bytes = response.plan.next_step.ui_form.blocker + val blocker = BlockerDescriptor.ADAPTER.decode(bytes) + BlockerTester.snapshot("REQUIREMENT_SNAPSHOT_NAME", blocker) + } + + @Test + fun testHandlerBetter() { + // Test a blocker you get back from calling a Plasma FlowHandler or RequirementHandler, + // using Plasma's test helpers to simplify things + val blocker = requirementHandler.testPlan(request).blockerDescriptor + BlockerTester.snapshot("REQUIREMENT_SNAPSHOT_NAME", blocker) + } + + @Test + fun testHandlerIgnoreId() { + // Test a blocker you get back from calling a Plasma FlowHandler or RequirementHandler, + // using Plasma's test helpers to simplify things and ignoring all "id" fields. + val blocker = requirementHandler.testPlan(request).blockerDescriptor + BlockerTester.snapshot("REQUIREMENT_SNAPSHOT_NAME", blocker, ignoredFields = listOf("**.id")) + } + + @Test + fun testMatcher() { + // Test some blocker you built by hand using the matcher. + val blocker = FormBlocker.Builder().elements(listOf(text("Sample"))).build() + // This calls BlockerTester.snapshot() + blocker shouldMatchSnapshot "SNAPSHOT_NAME" + } + } + ``` + + Snapshot names must be unique so give a name that is descriptive of the test and blocker being tested. + Snapshot names must be valid file names, and thus cannot contain forward slashes. + + Example Failure Output: + ``` + Failure: REQUIREMENT_SNAPSHOT_NAME blocker snapshot does not match the existing REQUIREMENT_SNAPSHOT_NAME.json + run `gradle {module}:updateSnapshots` to generate and overwrite the stale snapshots. + elements[0].text_element.text + Expected: MY_EXPECTED_TEXT + got: SOME_OTHER_UNEXPECTED_TEXT + ``` + + 7. You may need to run a `spotlessKotlin` or `spotlessApply` gradle task if it's a plugin in the repository. This will reformat the file to match the style guide. + + This will need to be run for any submodules that have been updated. For example if you have changed files in a module called `flows`, you need to run: + ```bash + bin/gradle :flows:spotlessApply + ``` + OR + ```bash + bin/gradle :flows:spotlessKotlin + ``` + + If `cash-server` is in the path, you can run the following command from the root of the `cash-server` repository: + ```bash + bin/gradle :::spotlessApply + ``` + + If the submodule you are updating doesn't have a `spotless` gradle task, then ignore this step. + + 8. Run the tests for each changed file after updating it so that the snapshot files are created. + + 9. If the test fails for any reason, review the error, make any fixes, and re-run the test method until it passes. + + 10. If the test passes, commit the changes with a commit message summarizing the change. Include the generated snapshot `.json` files in the commit. They will be located within a resources folder in the same sub-module as the test files changed. + + 11. You should only be committing updates to test files, build.gradle.kts files, libs.versions.toml and the generated snapshot files. + + # Post-Instructions + - Push your changes to the remote repository + - Create a pull request with the following command: + + ```bash + gh pr create --assignee "@me" --body "This PR migrates tests that inspect the output of `FormBlocker.Builder()` to use [snapshot testing](https://cash-dev-guide.sqprod.co/product_velocity/plasma/test/tools/?h=snapshot#snapshot-testing) instead. This is a more robust way to test the output of a blocker, and it will make it easier to refactor blockers in the future." --title "Migrate to snapshot testing for FormBlocker.Builder() usages" + ``` + +parameters: +- key: working_directory + input_type: string + requirement: user_prompt + description: The working directory of the service to migrate \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/change-log.yaml b/documentation/src/pages/recipes/data/recipes/change-log.yaml new file mode 100644 index 000000000000..dc9143612bbc --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/change-log.yaml @@ -0,0 +1,74 @@ +version: 1.0.0 +title: Generate Change Logs from Git Commits +description: Generate Change Logs from Git Commits +instructions: Follow the prompts to generate change logs from the provided git commits +activities: + - Retrieve and analyze commits + - Categorize changes + - Format changelog entries + - Update CHANGELOG.md +prompt: | + Task: Add change logs from Git Commits + 1. Please retrieve all commits between SHA {{start_sha}} and SHA {{end_sha}} (inclusive) from the repository. + + 2. For each commit: + - Extract the commit message + - Extract the commit date + - Extract any referenced issue/ticket numbers (patterns like #123, JIRA-456) + + 3. Organize the commits into the following categories: + - Features: New functionality added (commits that mention "feat", "feature", "add", etc.) + - Bug Fixes: Issues that were resolved (commits with "fix", "bug", "resolve", etc.) + - Performance Improvements: Optimizations (commits with "perf", "optimize", "performance", etc.) + - Documentation: Documentation changes (commits with "doc", "readme", etc.) + - Refactoring: Code restructuring (commits with "refactor", "clean", etc.) + - Other: Anything that doesn't fit above categories + + 4. Format the release notes as follows: + + # [Version/Date] + + ## Features + - [Feature description] - [PR #number](PR link) + + + ## Bug Fixes + - [Bug fix description] - [PR #number](PR link) + + [Continue with other categories...] + + Example: + - Implement summary and describe-commands for better sq integration - [PR #369](https://github.com/squareup/dx-ai-toolbox/pull/369) + + 5. Ensure all the commit items has a PR link. If you cannot find it, try again. If you still cannot find it, use the commit sha link instead. For example: [commit sha](commit url) + + 6. If commit messages follow conventional commit format (type(scope): message), use the type to categorize and include the scope in the notes. + + 7. Ignore merge commits and automated commits (like those from CI systems) unless they contain significant information. + + 8. For each category, sort entries by date (newest first). + + 9. formatted change logs as a markdown document + + 10. Create an empty CHANGELOG.md file if it does not exist + + 11. Read CHANGELOG.md and understand its format. + + 11. Insert the formatted change logs at the beginning of the CHANGELOG.md, and adjust its format to match the existing CHANGELOG.md format. Do not change any existing CHANGELOG.md content. +extensions: +- type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true +parameters: +- key: start_sha + input_type: string + requirement: user_prompt + description: the start sha of the git commits +- key: end_sha + input_type: string + requirement: user_prompt + description: the end sha of the git commits +author: + contact: lifeizhou-ap \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/create-kafka-topic.yaml b/documentation/src/pages/recipes/data/recipes/create-kafka-topic.yaml new file mode 100644 index 000000000000..2bf46d4c4cbd --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/create-kafka-topic.yaml @@ -0,0 +1,54 @@ +version: 1.0.0 +title: Create Kafka Topic +author: + contact: danielst-block +description: Create a new Kafka topic with specified parameters. +activities: + - Check for existing topic name conflicts + - Validate publisher and subscriber names + - Calculate optimal partition count + - Generate Kafka topic configuration + - Create topic directory and config files +parameters: + - key: topic_name + input_type: string + requirement: required + description: The name of the Kafka topic to create + - key: owner + input_type: string + requirement: required + description: The name/identifier of owner. + - key: publisher + input_type: string + requirement: required + description: The name/identifier of the publisher service or application + - key: subscribers + input_type: string + requirement: required + description: Comma-separated list of subscriber services or applications that will consume from this topic (e.g., "service1,service2,service3") + - key: throughput + input_type: string + requirement: optional + description: Expected throughput. Used to calculate optimal number of partitions for the topic + default: unknown +extensions: + - type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true +instructions: | + You are a Kafka topic creation assistant. Your job is to help create a new Kafka topic HCL + definitions with the specified configuration including topic name, publisher, owner, + subscribers, and optional throughput. Follow the existing folder structure and conventions. +prompt: | + 1. Create a {{ topic_name }} directory for a Kafka topic based on the following parameters: + - Topic name: {{ topic_name }} + - Owner: {{ owner }} + - Publisher: {{ publisher }} + - Subscribers: {{ subscribers }} + - Throughput: {{ throughput }} messages/second (if provided) + 2. Ensure the directory name does not conflict with any existing topics (notify the user and abort if it does). + 3. Check that the publisher and subscribers have been seen in other topics before to avoid typos. + 4. If throughput is provided - calculate the optimal number of partitions. Otherwise, default to 4 partitions. + 5. Include the calculated partition count in the topic configuration and explain the reasoning. \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/dev-guide-migration.yaml b/documentation/src/pages/recipes/data/recipes/dev-guide-migration.yaml new file mode 100644 index 000000000000..e49c75e76d58 --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/dev-guide-migration.yaml @@ -0,0 +1,45 @@ +version: 1.0.0 +title: dev guide migration from a specific file or files in a directory +description: dev guide migration from a specific file or files in a directory +instructions: Follow the prompts to migrate the doc page from source file(s) to target folder. +activities: + - Create target directory structure + - Migrate source docs to new location + - Format using example doc as reference + - Add new page to sidebar +prompt: | + Migrate the doc page from source file(s) at {{source_file}} to {{target_folder}}. Please follow the instructions below: + 1. Create the parent directory if the parent directory of the target file does not exist + 2. use {{example_file}} as a reference for the doc format + 3. retain all the information of the source file(s) in the target file + 4. If the page is not in the sidebar, add it in {{sidebar_file}} + 5. Ensure the target files + - has preserved the original content + - has correct formatting + - has clear and well-organized file structure + +extensions: +- type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true +parameters: +- key: source_file + input_type: file + requirement: user_prompt + description: the source file(s) or the folder to migrate +- key: target_folder + input_type: file + requirement: user_prompt + description: the target folder to migrate +- key: example_file + input_type: file + requirement: user_prompt + description: the example file to follow the doc format +- key: sidebar_file + input_type: file + requirement: user_prompt + description: the sidebar file to add the new doc page +author: + contact: lifeizhou-ap \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/fix-pr-ci-failures.yaml b/documentation/src/pages/recipes/data/recipes/fix-pr-ci-failures.yaml new file mode 100644 index 000000000000..48c8ba2fc2d4 --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/fix-pr-ci-failures.yaml @@ -0,0 +1,81 @@ +version: 0.1.0 +title: Fix PR CI failures +description: Iteratively fix errors detected by Kochiku CI on the current PR +instructions: follow the prompts to fix CI failures on your PR +activities: + - Fetch CI build status + - Analyze Kochiku build errors + - Split issues into individual tasks + - Fix and verify each issue iteratively + - Mark resolved issues +prompt: | + Guidelines: + - Use the commands provided to identify and fix CI failures in your PR + - Apply smallest-possible fixes and run scoped tests after each change + - Stop if the build is not in a failed state + - Process one issue at a time, fixing and testing before moving to the next + - Do not ask the user any questions, do your best to fix autonomously. + + Step 1: Find the CI build URL for your current commit + + Run this command to get the Kochiku build URL for your current commit: + ``` + gh pr view $(gh pr list --search $(git rev-parse HEAD) --json number -q ".[0].number") --json statusCheckRollup -q ".statusCheckRollup[] | select(.context == \"Kochiku\") | .targetUrl" + ``` + + Step 2: Check if the build has failed + + Extract the build ID from the URL (the number at the end) and check its state: + ``` + sq curl -s -L -H "Content-type: application/json" -H "Accept: application/json" "https://kochiku.sqprod.co/builds/BUILD_ID" | jq -r '.build.state' + ``` + + If the output is not "failed", then stop - there's nothing to fix yet. + + Step 3: Get your repository name + + ``` + basename -s .git $(git remote get-url origin) + ``` + + Step 4: Fetch the analysis of what failed + + Replace REPO and BUILD_ID with the values from steps 2 and 3: + ``` + sq curl -s -X POST \ + -H "Content-Type: application/json" \ + -d '{"repository":"REPO", "build_id": "BUILD_ID", "ci_type": "KOCHIKU"}' \ + "https://ci-results.sqprod.co/services/squareup.ciresults.service.CiResultsService/GetBuildMetadataWithAnalysis" | jq -r '.issues' > issues.json + ``` + + Step 5: Split the issues into individual files + + This command will take the issues.json file and create a separate file for each issue: + ``` + jq -c '.[] | @base64' issues.json | while read issue; do + decoded=$(echo $issue | base64 --decode) + index=$((index+1)) + echo $decoded > "issue_${index}.todo.json" + echo "Created issue_${index}.todo.json" + done + ``` + + Step 6: Process each issue + + For each issue file (issue_1.todo.json, issue_2.todo.json, etc.): + + Examine the issue file to understand the issue. Attempt to fix the issue + and verify the fix by running the appropriate commands (you'll have to infer these). + + Once you have fixed & verified the issue, rename the file from `issue_N.todo.json` to `issue_N.resolved.json` + and move on to the next issue. + + Keep iterating until there are no more `issue_N.todo.json` files. +extensions: +- type: builtin + name: developer + display_name: Developer + timeout: 600 + bundled: true +author: + contact: tmellor-block \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/migrate-cypress-test-to-playwright.yaml b/documentation/src/pages/recipes/data/recipes/migrate-cypress-test-to-playwright.yaml new file mode 100644 index 000000000000..cead33b5f5b3 --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/migrate-cypress-test-to-playwright.yaml @@ -0,0 +1,65 @@ +version: 1.0.0 +title: Migrate Cypress tests to Playwright +author: + contact: joahg +description: Migrate Cypress tests to Playwright +instructions: Your job is to migrate cypress tests to playwright tests. +activities: + - Analyze Cypress test file + - Convert Cypress syntax to Playwright + - Migrate custom commands and helpers + - Update imports and async handling + - Save Playwright test in target directory +extensions: +- type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true +prompt: | + You are tasked with migrating a Cypress test to Playwright. + + Cypress test file: {{ cypress_test_file }} + Target directory: {{ target_directory }} + + Please follow these steps: + + 1. **Analyze the Cypress test file**: Examine the Cypress test file at {{ cypress_test_file }}, including its structure, commands, and any custom helper functions used. + + 2. **Migrate the test structure**: Convert Cypress test syntax to Playwright: + - Replace `describe()` and `it()` with Playwright's `test.describe()` and `test()` + - Convert `cy.visit()` to `page.goto()` + - Convert `cy.get()` to appropriate Playwright locators + - Convert assertions from Cypress format to Playwright's `expect()` assertions + - Handle async/await patterns properly in Playwright + + 3. **Migrate Cypress commands**: Convert common Cypress commands to Playwright equivalents: + - `cy.click()` → `locator.click()` + - `cy.type()` → `locator.fill()` or `locator.type()` + - `cy.should()` → `expect(locator).to**()` + - `cy.wait()` → `page.waitForTimeout()` or better, specific wait conditions + - `cy.intercept()` → `page.route()` + + 4. **Migrate helper functions**: If the Cypress test uses custom commands or helper functions: + - Convert Cypress custom commands to Playwright helper functions + - Ensure helper functions are properly imported and available in the target directory + - Update function signatures to work with Playwright's page object + + 5. **Update imports and setup**: + - Add proper Playwright imports (`import { test, expect } from '@playwright/test'`) + - Remove Cypress-specific imports + - Ensure proper test configuration and setup + + 6. **Handle test data and fixtures**: Convert any Cypress fixtures or test data to work with Playwright + + Create the migrated Playwright test in the target directory, maintaining the same test coverage and functionality as the original Cypress test. Use the same base filename but with appropriate Playwright test naming conventions (e.g., .spec.ts or .test.ts). + +parameters: + - key: cypress_test_file + input_type: file + requirement: user_prompt + description: The specific Cypress test file to migrate (e.g., cypress/e2e/login.cy.js) + - key: target_directory + input_type: file + requirement: user_prompt + description: The target directory where the Playwright test should be created \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/migrate-from-poetry-to-uv.yaml b/documentation/src/pages/recipes/data/recipes/migrate-from-poetry-to-uv.yaml new file mode 100644 index 000000000000..242374083847 --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/migrate-from-poetry-to-uv.yaml @@ -0,0 +1,28 @@ +version: 1.0.0 +title: migrate from poetry to uv +description: migrate from poetry to uv +instructions: Follow the instructions to move the project from using `poetry` to `uv` +author: + contact: jamadeo +activities: + - Check if project already uses uv + - Run migration using uvx + - Remove poetry-related files and virtualenv + - Run uv sync +prompt: | + The current project uses `poetry` for Python environment and dependency management. We want to use `uv` instead. + + First, verify that the above is true. If the project is actually already using `uv`, you can stop. + + Start by running `uvx migrate-to-uv`. If you don't have `uv` installed, use `hermit install uv` to add it. If hermit isn't set up, use `hermit init` to do so. + + Once `migrate-to-uv` has run, delete any local virtualenvs (often located at ./.venv) and run `uv sync`. + + Grep for other uses of `poetry` in the project. If you can switch these commands to `uv`, do so. If not, just make a note of it. + +extensions: + - type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/pr-demo-planner.yaml b/documentation/src/pages/recipes/data/recipes/pr-demo-planner.yaml new file mode 100644 index 000000000000..90bba664d085 --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/pr-demo-planner.yaml @@ -0,0 +1,64 @@ +version: 1.0.0 +title: PR Demo Planner +author: + contact: lifei +description: Transforms technical Pull Requests into effective demonstrations that showcase functionality and value +activities: + - Analyze PR changes for demonstrable improvements + - Create demo script and narrative flow + - Build visual storyboard with before/after comparisons + - Suggest environments and test data for effective demo + - Translate technical changes into business value +instructions: | + You are a PR Demo Planner, an assistant specialized in transforming technical Pull Requests into engaging demonstrations. + + Your capabilities include: + 1. Analyzing PR changes to identify demonstrable features and improvements + 2. Creating structured demo scripts based on code changes + 3. Generating visual storyboards for demonstrations + 4. Helping prepare before/after comparisons that highlight improvements + 5. Crafting narratives that connect technical changes to business value + 6. Suggesting demo environments and test data + + When helping developers convert PRs to demos: + + - First understand the PR's purpose, scope, and technical changes + - Identify the most visually demonstrable aspects of the changes + - Create a narrative flow that showcases the improvements + - Focus on before/after comparisons when applicable + - Prepare for both technical and non-technical audiences + - Include setup instructions to ensure smooth demonstrations + - Suggest ways to highlight performance improvements or bug fixes + + You have access to reference materials: + - {{ recipe_dir }}/demo-formats.md for different demonstration approaches + - {{ recipe_dir }}/demo-script-templates.md for structured presentation formats + - {{ recipe_dir }}/technical-to-visual-guide.md for translating code changes to visual demonstrations + + Always aim to create demonstrations that clearly show the value of the changes made in the PR. + +extensions: +- type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true + +prompt: | + I need help converting my Pull Request into an effective demonstration. Please help me showcase the changes and improvements in a way that's clear and engaging. + + You can assist me with: + - Analyzing my PR to identify demonstrable features + - Creating a structured demo script + - Generating a visual storyboard + - Preparing before/after comparisons + - Crafting a narrative that explains the value + - Setting up an effective demo environment + + This is my PR: {{ pr_url }} + +parameters: + - key: pr_url + input_type: string + requirement: required + description: The URL of the PR to convert into a demo. \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/readme-bot.yaml b/documentation/src/pages/recipes/data/recipes/readme-bot.yaml new file mode 100644 index 000000000000..7946990ac681 --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/readme-bot.yaml @@ -0,0 +1,35 @@ +version: 1.0.0 +title: Readme Bot +author: + contact: DOsinga +description: Generates or updates a readme +instructions: You are a documentation expert +activities: + - Scan project directory for documentation context + - Generate a new README draft + - Compare new draft with existing README.md +extensions: +- type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true +prompt: | + Here's what to do step by step: + 1. The current folder is a software project. Scan it and learn as + much as possible. + 2. Based on what you find, write a read me file that contains a + general description of the project, how to get started and how + to run the tests. Only mention future plans if you find explicit + todo's. Do not write about future plans or licenses or anything + that you can't find explicit support for. + 3. Write this out as README.tmp.md. + 4. Look at the existing README.md. If it exists and the version you + wrote out is not really better, just tell the user that what + exists is really good enough and you can exit. + 5. If your version is better or no README.md exists, make your version + the current one + 6. If you are on main or master, create a new branch + 7. If the only chance at this point is the modification to the the + README.md, create a new commit + 8. Clean up after yourself, delete the README.tmp.md after use. \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/recipe-generator.yaml b/documentation/src/pages/recipes/data/recipes/recipe-generator.yaml new file mode 100644 index 000000000000..ada6d11021ae --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/recipe-generator.yaml @@ -0,0 +1,49 @@ +version: 1.0.0 +title: Recipe Generator +author: + contact: iYung +description: Creates other recipes +parameters: + - key: prompt + input_type: string + requirement: required + description: Description of what I want the recipe to do. Could be a file path +prompt: | + Recipes are a set of instructions. + + Here is what a recipe should look like: + ```yaml + version: 1.0.0 + title: Title of my recipe + description: Recipe Template + prompt: Write your prompt in here + extensions: + - type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true + #only required if recipe description asks for user input + #parameters are used in within prompt like \{\{ key }} and must be present + parameters: + - key: example_parameter + input_type: string or number + requirement: required or optional + description: Description of the paramater. + ``` + + Important notes: + - title is the name of the recipe + - description is a short summary of what the recipe does + - parameters are used within prompt like \{\{ key }} and must be present if mentioned in the recipe description + + Under prompt can you write instructions that achieve + {{ prompt }} + + If the above is a file path, read the file to determine the goal. +extensions: + - type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/remove-ai-artifacts-from-python-code.yaml b/documentation/src/pages/recipes/data/recipes/remove-ai-artifacts-from-python-code.yaml new file mode 100644 index 000000000000..7d8bc73c9c4c --- /dev/null +++ b/documentation/src/pages/recipes/data/recipes/remove-ai-artifacts-from-python-code.yaml @@ -0,0 +1,37 @@ +version: 1.0.0 +title: Python un-AI +author: + contact: douwe +description: Remove typical AI artifacts from Python code +instructions: Your job is to write a remove AI artifacts from Python code +activities: + - Remove redundant comments + - Fix exception handling + - Modernize typing + - Inline trivial functions +extensions: +- type: builtin + name: developer + display_name: Developer + timeout: 300 + bundled: true +prompt: | + Look at the file: {{ file_name }} + Apply the following fixes: + 1. Remove any comment that replicates the name of a function or describes the next statement + but does not add anything. Like if it says # call the server and it is followed by a + statement call_server(), that's pointless + 2. Any try.. except block where we catch bare Exception, remove that or if you can find a + specific exception to catch and it makes sense since we can actually do something better + catch that. But in general consider whether we need an exception like that, we don't want + to ignore errors and quite often the caller is in a better state to do the right thing + or even if it is a genuine error, the user can just take action + 3. Modernize the typing used (if any). Don't use List with a capital, just use list. Same for + Dict vs dict etc. Also remove Optional and replace with |None. Use | anywhere else where + it fits too. + 4. Inline trivial functions that are only called once, like reading text from a file. +parameters: + - key: file_name + input_type: file + requirement: user_prompt + description: the full path to the python file you want to sanitize \ No newline at end of file diff --git a/documentation/src/pages/recipes/index.tsx b/documentation/src/pages/recipes/index.tsx index d5cbcfcb7657..f6cbafb4aaa0 100644 --- a/documentation/src/pages/recipes/index.tsx +++ b/documentation/src/pages/recipes/index.tsx @@ -17,7 +17,7 @@ export default function RecipePage() { const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [currentPage, setCurrentPage] = useState(1); - const recipesPerPage = 20; + const recipesPerPage = 10; const uniqueExtensions = Array.from( new Set( From 328db625f873ec5720e02407e01d711cd07c9048 Mon Sep 17 00:00:00 2001 From: Ebony Louis Date: Mon, 30 Jun 2025 19:03:36 -0400 Subject: [PATCH 2/2] removing recipes --- .../analyze-java-monorepo-failures.yaml | 147 --------------- .../recipes/blokker-snapshot-migrator.yaml | 171 ------------------ .../data/recipes/fix-pr-ci-failures.yaml | 81 --------- 3 files changed, 399 deletions(-) delete mode 100644 documentation/src/pages/recipes/data/recipes/analyze-java-monorepo-failures.yaml delete mode 100644 documentation/src/pages/recipes/data/recipes/blokker-snapshot-migrator.yaml delete mode 100644 documentation/src/pages/recipes/data/recipes/fix-pr-ci-failures.yaml diff --git a/documentation/src/pages/recipes/data/recipes/analyze-java-monorepo-failures.yaml b/documentation/src/pages/recipes/data/recipes/analyze-java-monorepo-failures.yaml deleted file mode 100644 index 02c8b25f647d..000000000000 --- a/documentation/src/pages/recipes/data/recipes/analyze-java-monorepo-failures.yaml +++ /dev/null @@ -1,147 +0,0 @@ -version: 1.0.0 -title: Analyze java monorepo build failure -description: Analyze java monorepo build failure -instructions: follow the prompts to analyze java monorepo build failure -activities: - - Fetch failed build parts - - Download and parse logs - - Identify root causes - - Analyze test failures - - Summarize common issues and next steps - - Generate HTML report -prompt: | - Guidelines: - - Use curl instead of browser-based extensions like fetch. - - Use jq for JSON parsing and transformations. - - Prefer creating reusable shell functions for repeated steps. - - **Do NOT** make up any information, only use the information provided in the logs. - - Step 1: Fetch Failed Build Parts - - run the command - ``` - curl https://kochiku.sqprod.co/squareup/java/builds/{{build_id}}?format=json \ - | jq '[.build.build_parts[] | select(.status == "failed") \ - | {id, build_id, kind, attempt_count, status}]' > failed_builds.json - ``` - - Step 2: - For each failed build part, create a loop to handle each part: - 2.1 Fetch the last attempt - - find the last attempt via curl https://kochiku.sqprod.co/squareup/java/builds/{build_id}/parts/{id}?format=json | jq '.build_part.build_attempts[-1]' - 2.2 fetch the stdout.log.gz and junit-report.html (if present) - - get artifact_id of the log files including stdout.log.gz and junit-report.html (if present) in the last attempt - Example of json - { - "build_part": { - "id": 841284189, - "build_id": 9937415, - "kind": "deployable-loan-gateway", - "paths": [ - "loan-gateway:test" - ], - "status": "failed", - "elapsed_time": 812, - "build_attempts": [ - { - "id": 612181475, - "build_part_id": 841284189, - "files": [ - { - "build_artifact": { - "id": 2125669387, - "build_attempt_id": 612181475, - "created_at": "2025-05-02T15:01:19.000-07:00", - "updated_at": "2025-05-02T15:01:19.000-07:00", - "log_file": { - "url": "/build_artifacts/2125669387", - "name": "squareup/java/build_9937415/part_841284189/attempt_612181475/stdout.log.gz" - } - } - } - ] - } - ] - } - } - - construct the artifact_url https://kochiku.sqprod.co/build_artifacts/{artifact_id} - - add the part_url, stdout.log artifact_url and junit_report url in the failed_builds.json in the matching build_part block. If the file does not exist, set the field to null - 2.3 Analyze the stdout.log.gz file - - download stdout.log.gz file using curl command with follow redirect option - - find the error in this file error keywords of "error,failed,fails,fail,fatal"(case insensitive), and also include the 2 lines before and 10 lines after the found error, saved the result into a file with filtered_error_{artifact_id}.txt - - add the filtered_error_{artifact_id}.txt file name to the corresponding build part in failed_builds.json - 2.4 Root Cause Analysis for Filtered Error - - review filtered_error_{artifact_id}.txt - - Determine the root cause of the error - - Provide - 1. Root cause - - Provide a comprehensive explanation of why the failure occurred. - - Explain the specific failure context (e.g., what phase failed — dependency resolution, test execution, compilation, etc.). - - Mention any recent changes (code, dependencies, infra) if visible or likely from logs. - 2. Detailed Justifications: - - Quote the relevant error messages or stack traces verbatim from the logs. - - Describe what each error message means, what tool/component is involved (e.g., Maven, Gradle, JUnit, Kotlin compiler, etc.), and how it relates to the build. - - Provide background context — e.g., "This type of error is common when ..." or "Historically, this happens when ..." - - Discuss any patterns observed across multiple failed parts with similar symptoms. - 3. Suggestions for Fixing the Problem: - - Propose practical and actionable fixes. - - Suggest specific files or lines that may need changes (e.g., build.gradle, test class). - - If applicable, recommend mitigations (e.g., retry the build, invalidate caches, contact a service owner). - - For flaky tests or environmental issues, suggest diagnostics (e.g., re-run in isolation, check recent infra changes). - - Add this analysis (root cause, justification, and suggestions) to the relevant build part in failed_builds.json. - 2.5 Check for Test Failures - - If the stdout.log.gz file contains "tests_result=3", it indicates some tests failed in this build - - download junit-report.html use curl command (if available) with follow redirect option - - Parse the HTML to extract: - - Names of failed test classes and methods. - - Associated error messages or stack traces. - - save this information to filtered_test_error_{artifact_id}.html - 2.6 Root Cause Analysis for Test Failures - - review filtered_test_error_{artifact_id}.html - - Determine the root cause of the test failures - - Provide - 1. Root cause - - Explain why the test failed, including what condition, assertion, or runtime behavior caused it. - - Identify whether the issue is likely caused by a code regression, incorrect test setup, flaky behavior, environment issues, or external dependencies (e.g., services, databases). - - Mention if multiple test failures appear to share a root cause (e.g., shared fixture or mock failure). - 2. Detailed Justifications: - - Quote the exact test name (class and method), along with failure messages or stack traces. - - Explain what the test was trying to validate, and what part of the system it targets (e.g., business logic, edge case, error handling). - - Provide background: has this test failed before? Is it marked flaky or is the logic fragile? - - If applicable, explain why this issue might only occur in CI (e.g., timing, parallelism, test order). - 3. Suggestions for Fixing the Problem - - Suggested for fixing the problem - - add the root cause analysis, detailed justifications and potential fix suggestions to the matching build part in the `failed_builds.json` - - Step 3: Verify Completeness - - Verify each build part in failed_builds.json have been analyzed. - - If any of the build part has not been verified, repeat Step 2 for these build part - - Step 4: - - Review all build part analyses. - - Identify recurring root causes and classify them as common issues. - - Suggest immediate next steps that apply across multiple build parts (e.g., restarting a flaky test, checking dependency versions). - - Add a common_issues field and an immediate_next_steps field to the failed_builds.json file. - Step 5: - - Using the completed failed_builds.json, create a readable HTML report named: java_monorepo_build_analysis_{build_id}.html - - The HTML report should include: - - A list of issues (common issues are grouped together) - For each issue, list: - - The associated build parts and part urls - - Links to stdout.log.gz and junit-report.html. - - Root cause - - Justifications - - Fix suggestions - - Immediate next steps for fixing the issues. -extensions: -- type: builtin - name: developer - display_name: Developer - timeout: 300 - bundled: true -parameters: -- key: build_id - input_type: number - requirement: user_prompt - description: the failed build id to analyze -author: - contact: lifeizhou-ap \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/blokker-snapshot-migrator.yaml b/documentation/src/pages/recipes/data/recipes/blokker-snapshot-migrator.yaml deleted file mode 100644 index d9068f774e69..000000000000 --- a/documentation/src/pages/recipes/data/recipes/blokker-snapshot-migrator.yaml +++ /dev/null @@ -1,171 +0,0 @@ -version: 1.0.0 -title: Blokker Snapshot Migrator -author: - contact: jadam -description: Migrate to Snapshot Testing for FormBlockers -instructions: Follow the prompts to migrate a service to snapshot testing -activities: - - Create a migration branch - - Add plasma-testing dependency to Gradle config - - Identify usages of FormBlocker.Builder() - - Locate and update associated test classes - - Commit test and snapshot changes - - Create and submit a pull request -extensions: -- type: builtin - name: developer - display_name: Developer - timeout: 600 - bundled: true -prompt: | - # Pre-Instructions - - ## Working Directory - - No files outside the directory {{working_directory}} should be modified. - - No commands should be run outside of the directory {{working_directory}}. - - ## Gradle - - To run gradle, use `bin/gradle ` from the project root. There is NO `gradlew` script. - - If you are working in cash-server, the repository consists of many projects. You should usually specify a specific project with `-p` any time you are calling gradle from the root directory. The gradle to use is located at `cash-server/bin/gradle` even if you're in a subproject. - - # Instructions - Perform the following steps to migrate to snapshot testing: - - 1. Create a new branch and check it out for the migration using the following command: - - ```bash - git checkout -b $USER/$(date +%m%d%Y)-formblocker-snapshot-migration - ```` - - 2. Ensure that the `plasma-testing` library is added to the `gradle/libs.versions.toml` file. If it is not, add it: - - ```toml - [libraries] - plasmaTesting = { module = "com.squareup.plasma:plasma-testing", version = "2025.04.01-1743540086-eeb2f79" } - ``` - - 3. Find all files that FormBlocker.Builder() is used in. - - 4. Locate the associated test classes. These are the files to update. - - 5. Update the `build.gradle.kts` files of the modules that contain the test classes to include the following dependencies: - - If `cash-server` is not in the current path: - ```kotlin - dependencies { - testImplementation(libs.plasmaTesting) - } - ``` - - If `cash-server` is in the current path: - ```kotlin - dependencies { - testImplementation(project(":plasma:plasma-testing")) - } - ``` - - 6. Update any test methods from these classes that test the outputs of a FormBlocker.Builder() to use the BlockerTester.snapshot() method. - - Make sure that any modified test files have the import `import com.squareup.cash.blockertesting.BlockerTester`. - - Examples: - ```kotlin - import com.squareup.cash.blockertesting.BlockerTester - - class SomeBlockerTest { - @Inject private lateinit var requirementHandler: SomeRequirementHandler - - @Test - fun testManual() { - // Test some blocker you built by hand. - // This isn't useful in practice, but it's simple and illustrative - val blocker = FormBlocker.Builder().elements(listOf(text("Sample"))).build() - BlockerTester.snapshot("SNAPSHOT_NAME", blocker) - } - - @Test - fun testHandler() { - // Test a blocker you get back from calling a Plasma FlowHandler or RequirementHandler - val response = requirementHandler.plan(request) - val bytes = response.plan.next_step.ui_form.blocker - val blocker = BlockerDescriptor.ADAPTER.decode(bytes) - BlockerTester.snapshot("REQUIREMENT_SNAPSHOT_NAME", blocker) - } - - @Test - fun testHandlerBetter() { - // Test a blocker you get back from calling a Plasma FlowHandler or RequirementHandler, - // using Plasma's test helpers to simplify things - val blocker = requirementHandler.testPlan(request).blockerDescriptor - BlockerTester.snapshot("REQUIREMENT_SNAPSHOT_NAME", blocker) - } - - @Test - fun testHandlerIgnoreId() { - // Test a blocker you get back from calling a Plasma FlowHandler or RequirementHandler, - // using Plasma's test helpers to simplify things and ignoring all "id" fields. - val blocker = requirementHandler.testPlan(request).blockerDescriptor - BlockerTester.snapshot("REQUIREMENT_SNAPSHOT_NAME", blocker, ignoredFields = listOf("**.id")) - } - - @Test - fun testMatcher() { - // Test some blocker you built by hand using the matcher. - val blocker = FormBlocker.Builder().elements(listOf(text("Sample"))).build() - // This calls BlockerTester.snapshot() - blocker shouldMatchSnapshot "SNAPSHOT_NAME" - } - } - ``` - - Snapshot names must be unique so give a name that is descriptive of the test and blocker being tested. - Snapshot names must be valid file names, and thus cannot contain forward slashes. - - Example Failure Output: - ``` - Failure: REQUIREMENT_SNAPSHOT_NAME blocker snapshot does not match the existing REQUIREMENT_SNAPSHOT_NAME.json - run `gradle {module}:updateSnapshots` to generate and overwrite the stale snapshots. - elements[0].text_element.text - Expected: MY_EXPECTED_TEXT - got: SOME_OTHER_UNEXPECTED_TEXT - ``` - - 7. You may need to run a `spotlessKotlin` or `spotlessApply` gradle task if it's a plugin in the repository. This will reformat the file to match the style guide. - - This will need to be run for any submodules that have been updated. For example if you have changed files in a module called `flows`, you need to run: - ```bash - bin/gradle :flows:spotlessApply - ``` - OR - ```bash - bin/gradle :flows:spotlessKotlin - ``` - - If `cash-server` is in the path, you can run the following command from the root of the `cash-server` repository: - ```bash - bin/gradle :::spotlessApply - ``` - - If the submodule you are updating doesn't have a `spotless` gradle task, then ignore this step. - - 8. Run the tests for each changed file after updating it so that the snapshot files are created. - - 9. If the test fails for any reason, review the error, make any fixes, and re-run the test method until it passes. - - 10. If the test passes, commit the changes with a commit message summarizing the change. Include the generated snapshot `.json` files in the commit. They will be located within a resources folder in the same sub-module as the test files changed. - - 11. You should only be committing updates to test files, build.gradle.kts files, libs.versions.toml and the generated snapshot files. - - # Post-Instructions - - Push your changes to the remote repository - - Create a pull request with the following command: - - ```bash - gh pr create --assignee "@me" --body "This PR migrates tests that inspect the output of `FormBlocker.Builder()` to use [snapshot testing](https://cash-dev-guide.sqprod.co/product_velocity/plasma/test/tools/?h=snapshot#snapshot-testing) instead. This is a more robust way to test the output of a blocker, and it will make it easier to refactor blockers in the future." --title "Migrate to snapshot testing for FormBlocker.Builder() usages" - ``` - -parameters: -- key: working_directory - input_type: string - requirement: user_prompt - description: The working directory of the service to migrate \ No newline at end of file diff --git a/documentation/src/pages/recipes/data/recipes/fix-pr-ci-failures.yaml b/documentation/src/pages/recipes/data/recipes/fix-pr-ci-failures.yaml deleted file mode 100644 index 48c8ba2fc2d4..000000000000 --- a/documentation/src/pages/recipes/data/recipes/fix-pr-ci-failures.yaml +++ /dev/null @@ -1,81 +0,0 @@ -version: 0.1.0 -title: Fix PR CI failures -description: Iteratively fix errors detected by Kochiku CI on the current PR -instructions: follow the prompts to fix CI failures on your PR -activities: - - Fetch CI build status - - Analyze Kochiku build errors - - Split issues into individual tasks - - Fix and verify each issue iteratively - - Mark resolved issues -prompt: | - Guidelines: - - Use the commands provided to identify and fix CI failures in your PR - - Apply smallest-possible fixes and run scoped tests after each change - - Stop if the build is not in a failed state - - Process one issue at a time, fixing and testing before moving to the next - - Do not ask the user any questions, do your best to fix autonomously. - - Step 1: Find the CI build URL for your current commit - - Run this command to get the Kochiku build URL for your current commit: - ``` - gh pr view $(gh pr list --search $(git rev-parse HEAD) --json number -q ".[0].number") --json statusCheckRollup -q ".statusCheckRollup[] | select(.context == \"Kochiku\") | .targetUrl" - ``` - - Step 2: Check if the build has failed - - Extract the build ID from the URL (the number at the end) and check its state: - ``` - sq curl -s -L -H "Content-type: application/json" -H "Accept: application/json" "https://kochiku.sqprod.co/builds/BUILD_ID" | jq -r '.build.state' - ``` - - If the output is not "failed", then stop - there's nothing to fix yet. - - Step 3: Get your repository name - - ``` - basename -s .git $(git remote get-url origin) - ``` - - Step 4: Fetch the analysis of what failed - - Replace REPO and BUILD_ID with the values from steps 2 and 3: - ``` - sq curl -s -X POST \ - -H "Content-Type: application/json" \ - -d '{"repository":"REPO", "build_id": "BUILD_ID", "ci_type": "KOCHIKU"}' \ - "https://ci-results.sqprod.co/services/squareup.ciresults.service.CiResultsService/GetBuildMetadataWithAnalysis" | jq -r '.issues' > issues.json - ``` - - Step 5: Split the issues into individual files - - This command will take the issues.json file and create a separate file for each issue: - ``` - jq -c '.[] | @base64' issues.json | while read issue; do - decoded=$(echo $issue | base64 --decode) - index=$((index+1)) - echo $decoded > "issue_${index}.todo.json" - echo "Created issue_${index}.todo.json" - done - ``` - - Step 6: Process each issue - - For each issue file (issue_1.todo.json, issue_2.todo.json, etc.): - - Examine the issue file to understand the issue. Attempt to fix the issue - and verify the fix by running the appropriate commands (you'll have to infer these). - - Once you have fixed & verified the issue, rename the file from `issue_N.todo.json` to `issue_N.resolved.json` - and move on to the next issue. - - Keep iterating until there are no more `issue_N.todo.json` files. -extensions: -- type: builtin - name: developer - display_name: Developer - timeout: 600 - bundled: true -author: - contact: tmellor-block \ No newline at end of file