[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F1VJSZ9Q7Z48NWTYB98KFW":3,"skill-same:01M6F1VJSZ9Q7Z48NWTYB98KFW":55},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":28,"linkOnly":29,"markdownContent":30,"markdownBody":31,"frontMatter":32,"refName":33,"commitSha":34,"skillDirectory":35,"forksCount":36,"repositoryHtmlUrl":37,"repositoryHomepageUrl":38,"ownerHtmlUrl":39,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":40,"install":41,"resources":54},"01M6F1VJSZ9Q7Z48NWTYB98KFW","pytest.fix_ci_tests",null,"Analyze and fix failure of tests in GitHub CI","causify-ai\u002Fhelpers","causify-ai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F121828442?v=4","01M6BZFTHW2MQR7FWK8CDW0DRA","Causify.AI","01M6F1K6CCKKF8YKTBN4ZV509G",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Fpytest.fix_ci_tests\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27],"fix ci","ci","pytest fix ci tests","fix","pytest","tests","github","analyze","haiku","2026-11-10 10:12:30",false,"---\ndescription: Analyze and fix failure of tests in GitHub CI\nmodel: haiku\n---\n\n# Goal\n\n- Given a run of the GitHub CI analyze the failures and fix the failing tests\n\n# Workflow\n\n- Read `.claude\u002Fskills\u002Fpytest.rules.md`\n\n## Parse Logs From CI\n\n- Parse the output of `invoke gh_workflow_list` which contains information on the\n  failing tests\n- The log of the failing tests on the CI is stored in a file `\u003CCI_LOG>` like:\n\n  ```bash\n  # Log is in 'tmp.failure.check_if_the_linter_was_run.gp_scratch_19.txt'\n  ```\n\n- The list of failing tests `\u003CFAILING_TESTS>` is in a file `\u003CREPRO_SCRIPT>` like:\n\n  ```bash\n  ... # To run the tests:\n  ... > .\u002Ftmp.pytest_repro.fast_tests.sh\n  ```\n\n## Check Whether the Failure Reproduces Locally\n\n- Parse `\u003CCI_LOG>`\n- Run the script `\u003CREPRO_SCRIPT>` locally to check whether `\u003CFAILING_TESTS>` fail\n  there too\n  - For the tests that involve running Docker \u002F Apple containers run the same tests\n    with different builds, as per `## Analyze the Effect of Container Builds` in\n    `.claude\u002Fskills\u002Fpytest.rules.md`\n- Note any difference in behavior between CI and local: e.g., environment\n  variables, secrets, container build, or flakiness. `\u002Fpytest.fix_local_tests`\n  cannot see this CI-specific context, so capture it here\n\n## Diagnose and Fix\n\n- Use `\u002Fpytest.fix_local_tests` passing `\u003CREPRO_SCRIPT>` as `\u003CFAILURE_INFO>` to\n  diagnose the root cause and fix the failing tests\n  - If a failure only reproduces on CI (not locally), diagnose the CI-specific\n    cause directly instead (env, secrets, container build, flakiness) and fix it\n- Report a table with the information of what tests are passing in the CI, locally,\n  and why they are failing in the CI and locally, in the file\n  `plan-pytest.fix_ci_tests.md` in the current dir\n- Verify the fixes work correctly as per `# Verification of the Fix` from\n  `.claude\u002Fskills\u002Fpytest.rules.md`\n\n## Ask the User to Commit\n- Ask the user to review and commit the changes\n- Wait for the CI to pick up the changes and run the tests, and repeat the workflow\n\n# Verification\n\n- [ ] `plan-pytest.fix_ci_tests.md` lists a fix for every failing test\n- [ ] Every fix follows `# Verification of the Fix` in\n      `.claude\u002Fskills\u002Fpytest.rules.md`\n- [ ] The failing tests pass both on the CI and locally after the fix\n","# Goal\n\n- Given a run of the GitHub CI analyze the failures and fix the failing tests\n\n# Workflow\n\n- Read `.claude\u002Fskills\u002Fpytest.rules.md`\n\n## Parse Logs From CI\n\n- Parse the output of `invoke gh_workflow_list` which contains information on the\n  failing tests\n- The log of the failing tests on the CI is stored in a file `\u003CCI_LOG>` like:\n\n  ```bash\n  # Log is in 'tmp.failure.check_if_the_linter_was_run.gp_scratch_19.txt'\n  ```\n\n- The list of failing tests `\u003CFAILING_TESTS>` is in a file `\u003CREPRO_SCRIPT>` like:\n\n  ```bash\n  ... # To run the tests:\n  ... > .\u002Ftmp.pytest_repro.fast_tests.sh\n  ```\n\n## Check Whether the Failure Reproduces Locally\n\n- Parse `\u003CCI_LOG>`\n- Run the script `\u003CREPRO_SCRIPT>` locally to check whether `\u003CFAILING_TESTS>` fail\n  there too\n  - For the tests that involve running Docker \u002F Apple containers run the same tests\n    with different builds, as per `## Analyze the Effect of Container Builds` in\n    `.claude\u002Fskills\u002Fpytest.rules.md`\n- Note any difference in behavior between CI and local: e.g., environment\n  variables, secrets, container build, or flakiness. `\u002Fpytest.fix_local_tests`\n  cannot see this CI-specific context, so capture it here\n\n## Diagnose and Fix\n\n- Use `\u002Fpytest.fix_local_tests` passing `\u003CREPRO_SCRIPT>` as `\u003CFAILURE_INFO>` to\n  diagnose the root cause and fix the failing tests\n  - If a failure only reproduces on CI (not locally), diagnose the CI-specific\n    cause directly instead (env, secrets, container build, flakiness) and fix it\n- Report a table with the information of what tests are passing in the CI, locally,\n  and why they are failing in the CI and locally, in the file\n  `plan-pytest.fix_ci_tests.md` in the current dir\n- Verify the fixes work correctly as per `# Verification of the Fix` from\n  `.claude\u002Fskills\u002Fpytest.rules.md`\n\n## Ask the User to Commit\n- Ask the user to review and commit the changes\n- Wait for the CI to pick up the changes and run the tests, and repeat the workflow\n\n# Verification\n\n- [ ] `plan-pytest.fix_ci_tests.md` lists a fix for every failing test\n- [ ] Every fix follows `# Verification of the Fix` in\n      `.claude\u002Fskills\u002Fpytest.rules.md`\n- [ ] The failing tests pass both on the CI and locally after the fix\n",{"model":27,"description":7},"master","804ae3e928c04740cec553be0eb28c8d06ff420e",".claude\u002Fskills\u002Fpytest.fix_ci_tests",1,"https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers","https:\u002F\u002Fcausify-ai.github.io\u002Fhelpers\u002F","https:\u002F\u002Fgithub.com\u002Fcausify-ai","2026-11-02 21:54:29",{"source":8,"skillName":5,"commands":42,"prompt":52,"zipAvailable":53},[43,46,49],{"tool":44,"command":45},"npx","npx skills add causify-ai\u002Fhelpers --skill pytest.fix_ci_tests",{"tool":47,"command":48},"bunx","bunx skills add causify-ai\u002Fhelpers --skill pytest.fix_ci_tests",{"tool":50,"command":51},"pnpm","pnpm dlx skills add causify-ai\u002Fhelpers --skill pytest.fix_ci_tests","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Fpytest.fix_ci_tests\u002FSKILL.md",true,[],[56,77,95,107,116,130],{"skillNo":57,"name":58,"nameZh":6,"description":59,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":60,"categories":61,"keywords":67,"publishedAt":28},"01M6F209RASRBEK7GBNG5M00K0","tutorial_in_60_mins.propagate_docker_changes","Sync tutorial and class-project Docker files to match project_template","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftutorial_in_60_mins.propagate_docker_changes\u002FSKILL.md",[62],{"categoryNo":63,"categoryName":64,"taxonomyType":65,"taxonomyTypeDesc":66},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[68,69,70,71,72,73,27,74,75,76],"docker","tutorial","tutorial in 60 mins propagate docker changes","propagate","template","sync","files","project","match",{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":86,"publishedAt":28},"01M6F207XZ5YDAJ0KNDRE6EN0R","tutorial_in_60_mins.merge_markdown","Merge the content of a markdown file into a Jupyter notebook","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftutorial_in_60_mins.merge_markdown\u002FSKILL.md",[83],{"categoryNo":84,"categoryName":85,"taxonomyType":65,"taxonomyTypeDesc":66},"01JBSEEDCAT000000000000002","文档处理",[87,88,69,89,90,91,27,92,93,94],"markdown","merge","tutorial in 60 mins merge markdown","notebook","jupyter","file","jupyter notebook","content",{"skillNo":96,"name":97,"nameZh":6,"description":98,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":28},"01M6F2059X95Q1A13HD67E9JRF","tutorial_in_60_mins.format","Format a directory to follow the \"Learn X in 60 Minutes\" tutorial conventions","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftutorial_in_60_mins.format\u002FSKILL.md",[],[102,69,103,104,105,27,106],"tutorial in 60 mins format","format","directory","learn","conventions",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":113,"publishedAt":28},"01M6F202MDHMNYD5S1YHG2PKZD","tutorial_in_60_mins.create","Create a tutorial directory for the Learn X in 60 Minutes conventions","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftutorial_in_60_mins.create\u002FSKILL.md",[],[114,69,115,105,104,106],"tutorial in 60 mins create","create",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":122,"publishedAt":28},"01M6F2004BW13GQ59N3RGSAYVN","todo.reorg_in_progress","Reorganize ai_task_queue.md so in-progress tasks, not-started tasks, and mislabeled topic headers sit under the right H1 stage","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftodo.reorg_in_progress\u002FSKILL.md",[],[123,124,125,126,127,128,129],"progress","todo","todo reorg in progress","tasks","queue","task","stage",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":136,"publishedAt":28},"01M6F1ZXN0G6HBD08GT8HE5FYA","todo.reorg_headers","Reorganize ai_task_queue.md .md so every H2 topic matches ALL TOPICS and every H3 task sits under the right topic, keeping its H1 stage","https:\u002F\u002Fgithub.com\u002Fcausify-ai\u002Fhelpers\u002Fblob\u002Fmaster\u002F.claude\u002Fskills\u002Ftodo.reorg_headers\u002FSKILL.md",[],[137,124,127,128,129],"todo reorg headers"]