Skip to content

Commit c8ce952

Browse files
committed
chore: add skills
1 parent daa7bde commit c8ce952

5 files changed

Lines changed: 605 additions & 0 deletions

File tree

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
---
2+
name: debug-generated-project
3+
description: Debugs issues users encounter with Tuist-generated projects by reproducing the scenario locally, building Tuist from source when needed, and triaging whether it is a bug, misconfiguration, or something that needs team input. Use when users report generation failures, build errors after generation, or unexpected project behavior.
4+
---
5+
6+
# Debug Tuist Project Issue
7+
8+
## Quick Start
9+
10+
1. Ask the user to describe the issue and the project setup (targets, dependencies, configurations, platform).
11+
2. Confirm the issue exists with the latest release by running `mise exec tuist@latest -- tuist generate` against a reproduction project.
12+
3. If confirmed, clone the Tuist repository and build from source to test against main.
13+
4. Triage: fix the bug and open a PR, advise on misconfiguration, or recommend the user files an issue with a reproduction.
14+
15+
## Step 1: Gather Context
16+
17+
Ask the user for:
18+
19+
- What command they ran (e.g. `tuist generate`)
20+
- The error message or unexpected behavior
21+
- **When the issue happens**: generation time, compile time, or runtime (app launch or later)
22+
- Their project structure: targets, platforms, dependencies (SwiftPM, XCFrameworks, local packages)
23+
- Their `Project.swift` and `Tuist.swift` content (or relevant excerpts)
24+
- Their Tuist version (`tuist version`)
25+
26+
The answer to "when" determines the verification strategy:
27+
28+
- **Generation time**: the issue might be a Tuist bug or a project misconfiguration. Reproduce with `tuist generate`.
29+
- **Compile time**: the generated project has incorrect build settings, missing sources, or wrong dependency wiring. Reproduce with `xcodebuild build` after generation.
30+
- **Runtime**: the app builds but crashes or misbehaves on launch or during use. Reproduce by installing and launching on a simulator.
31+
32+
## Step 2: Reproduce with the latest release
33+
34+
Before investigating the source code, confirm the issue is not already fixed in the latest release.
35+
36+
### Set up a temporary reproduction project
37+
38+
```bash
39+
REPRO_DIR=$(mktemp -d)
40+
cd "$REPRO_DIR"
41+
```
42+
43+
Create minimal `Tuist.swift`, `Project.swift`, and source files that reproduce the user's scenario. Keep it as small as possible while still triggering the issue.
44+
45+
### Run generation with the latest Tuist release
46+
47+
```bash
48+
mise exec tuist@latest -- tuist generate --no-open --path "$REPRO_DIR"
49+
```
50+
51+
If the issue involves dependencies, install them first:
52+
53+
```bash
54+
mise exec tuist@latest -- tuist install --path "$REPRO_DIR"
55+
```
56+
57+
### Check the result
58+
59+
- If generation succeeds and the issue is gone, tell the user to update to the latest version.
60+
- If the issue persists, continue to Step 3.
61+
62+
## Step 3: Build Tuist from Source
63+
64+
Clone the repository and build the `tuist` executable and `ProjectDescription` library from source to test against the latest code on `main`.
65+
66+
```bash
67+
TUIST_SRC=$(mktemp -d)
68+
git clone --depth 1 https://github.com/tuist/tuist.git "$TUIST_SRC"
69+
cd "$TUIST_SRC"
70+
swift build --product tuist --product ProjectDescription --replace-scm-with-registry
71+
```
72+
73+
The built binary will be at `.build/debug/tuist`. Use it to test the reproduction project:
74+
75+
```bash
76+
"$TUIST_SRC/.build/debug/tuist" generate --no-open --path "$REPRO_DIR"
77+
```
78+
79+
### If the issue is fixed on main
80+
81+
Tell the user the fix is already on `main`, and it hasn't been released, tell them it'll be in the nest release and point them to the relevant commit if you can identify it.
82+
83+
### If the issue persists on main
84+
85+
Continue to Step 4.
86+
87+
## Step 4: Triage the Issue
88+
89+
Investigate the Tuist source code to understand why the issue occurs.
90+
91+
### Outcome A: It is a bug
92+
93+
1. Identify the root cause in the source code.
94+
2. Apply the fix.
95+
3. Verify by rebuilding and running against the reproduction project:
96+
```bash
97+
cd "$TUIST_SRC"
98+
swift build --product tuist --product ProjectDescription --replace-scm-with-registry
99+
"$TUIST_SRC/.build/debug/tuist" generate --no-open --path "$REPRO_DIR"
100+
```
101+
4. Zip the reproduction project and include it in the PR:
102+
```bash
103+
cd "$REPRO_DIR" && cd ..
104+
zip -r reproduction.zip "$(basename "$REPRO_DIR")" -x '*.xcodeproj/*' -x '*.xcworkspace/*' -x 'Derived/*' -x '.build/*'
105+
```
106+
5. Open a PR on the Tuist repository with:
107+
- The fix
108+
- The zipped reproduction project attached or committed as a fixture
109+
- A clear description of the root cause and how to verify the fix
110+
111+
### Outcome B: It is a misconfiguration
112+
113+
Tell the user what is wrong and how to fix it. Common misconfigurations:
114+
115+
- Missing `tuist install` before `tuist generate` when using external dependencies
116+
- Incorrect source or resource globs that exclude or double-include files
117+
- Mismatched build configurations between the project and external dependencies
118+
- Wrong product types for dependencies (static vs dynamic)
119+
- Missing `-ObjC` linker flag for Objective-C dependencies
120+
- Using `sources` and `resources` globs together with `buildableFolders`
121+
122+
Provide the corrected manifest snippet so the user can apply the fix directly.
123+
124+
### Outcome C: Unclear or needs team input
125+
126+
If you cannot determine whether it is a bug or misconfiguration, recommend the user:
127+
128+
1. Open a GitHub issue at https://github.com/tuist/tuist/issues with:
129+
- The reproduction project (zipped)
130+
- The error output
131+
- Their Tuist version and environment details
132+
133+
Provide a summary of what you investigated and what you ruled out, so the user does not have to repeat the triage.
134+
135+
## Build Verification
136+
137+
When testing a fix, always verify the full cycle:
138+
139+
```bash
140+
# Build the patched tuist
141+
cd "$TUIST_SRC"
142+
swift build --product tuist --product ProjectDescription --replace-scm-with-registry
143+
144+
# Install dependencies if needed
145+
"$TUIST_SRC/.build/debug/tuist" install --path "$REPRO_DIR"
146+
147+
# Generate the project
148+
"$TUIST_SRC/.build/debug/tuist" generate --no-open --path "$REPRO_DIR"
149+
150+
# Build the generated project
151+
xcodebuild build \
152+
-workspace "$REPRO_DIR"/*.xcworkspace \
153+
-scheme <scheme> \
154+
-destination "platform=iOS Simulator,name=iPhone 16 Pro"
155+
```
156+
157+
## Runtime Verification
158+
159+
When the user reports a runtime issue (crash on launch, missing resources at runtime, wrong bundle structure, or unexpected behavior), you must go beyond building and actually launch the app on a simulator.
160+
161+
### Launch and monitor for crashes
162+
163+
```bash
164+
# Boot a simulator
165+
xcrun simctl boot "iPhone 16 Pro" 2>/dev/null || true
166+
167+
# Build for the simulator
168+
xcodebuild build \
169+
-workspace "$REPRO_DIR"/*.xcworkspace \
170+
-scheme <scheme> \
171+
-destination "platform=iOS Simulator,name=iPhone 16 Pro" \
172+
-derivedDataPath "$REPRO_DIR/DerivedData"
173+
174+
# Install the app
175+
xcrun simctl install booted "$REPRO_DIR/DerivedData/Build/Products/Debug-iphonesimulator/<AppName>.app"
176+
177+
# Launch and monitor — this will print crash info if the app terminates abnormally
178+
xcrun simctl launch --console-pty booted <bundle-identifier>
179+
```
180+
181+
The `--console-pty` flag streams the app's stdout/stderr so you can observe logs and crash output directly. Watch for:
182+
183+
- **Immediate crash on launch**: usually a missing framework, wrong bundle ID, missing entitlements, or stripped ObjC categories (`-ObjC` linker flag missing)
184+
- **Crash after a few seconds**: often missing resources (images, storyboards, XIBs, asset catalogs) or a bundle structure mismatch
185+
- **Runtime misbehavior without crash**: wrong resource paths, missing localization files, or incorrect Info.plist values
186+
187+
### Check crash logs
188+
189+
If the app crashes without useful console output, pull the crash log:
190+
191+
```bash
192+
# List recent crash logs for the app
193+
find ~/Library/Logs/DiagnosticReports -name "<AppName>*" -newer "$REPRO_DIR" -print
194+
```
195+
196+
Read the crash log to identify the crashing thread and the faulting symbol.
197+
198+
## Done Checklist
199+
200+
- Gathered enough context from the user to reproduce the issue
201+
- Determined whether the issue is at generation time, compile time, or runtime
202+
- Confirmed whether the issue exists in the latest release
203+
- Tested against Tuist built from source (main branch)
204+
- If runtime issue: launched the app on a simulator and verified the crash or misbehavior
205+
- Triaged the issue as a bug, misconfiguration, or unclear
206+
- If bug: applied fix, verified it, and opened a PR with reproduction project
207+
- If misconfiguration: provided corrected manifest to the user
208+
- If unclear: gave the user a summary and recommended next steps
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
---
2+
name: fix-flaky-tests
3+
description: Fixes a specific flaky test by analyzing its failure patterns from Tuist, identifying the root cause, and applying a targeted correction. Typically invoked with a Tuist test case URL in the format such as `https://tuist.dev/{account}/{project}/tests/test-cases/{id}`.
4+
---
5+
6+
# Fix Flaky Test
7+
8+
## Quick Start
9+
10+
You'll typically receive a Tuist test case URL or identifier. Follow these steps to investigate and fix it:
11+
12+
1. Run `tuist test case show <id-or-identifier> --json` to get reliability metrics for the test.
13+
2. Run `tuist test case run list Module/Suite/TestCase --flaky --json` to see flaky run patterns.
14+
3. Run `tuist test case run show <run-id> --json` on failing flaky runs to get failure messages and file paths.
15+
4. Read the test source at the reported path and line, identify the flaky pattern, and fix it.
16+
5. Verify by running the test multiple times to confirm it passes consistently.
17+
18+
## Investigation
19+
20+
### 1. Get test case metrics
21+
22+
You can pass either the UUID or the `Module/Suite/TestCase` identifier:
23+
24+
```bash
25+
tuist test case show <id> --json
26+
tuist test case show Module/Suite/TestCase --json
27+
```
28+
29+
Key fields:
30+
- `reliability_rate` — percentage of successful runs (higher is better)
31+
- `flakiness_rate` — percentage of runs marked flaky in the last 30 days
32+
- `total_runs` / `failed_runs` — volume context
33+
- `last_status` — current state
34+
35+
### 2. View flaky run history
36+
37+
```bash
38+
tuist test case run list Module/Suite/TestCase --flaky --json
39+
```
40+
41+
The identifier uses the format `ModuleName/SuiteName/TestCaseName` or `ModuleName/TestCaseName` when there is no suite. This returns only runs that were detected as flaky.
42+
43+
### 3. View full run history
44+
45+
```bash
46+
tuist test case run list Module/Suite/TestCase --json --page-size 20
47+
```
48+
49+
Look for patterns:
50+
- Does it fail on specific branches?
51+
- Does it fail only on CI (`is_ci: true`) or also locally?
52+
- Are failures clustered around specific commits?
53+
54+
### 4. Get failure details
55+
56+
```bash
57+
tuist test case run show <run-id> --json
58+
```
59+
60+
Key fields:
61+
- `failures[].message` — the assertion or error message
62+
- `failures[].path`source file path
63+
- `failures[].line_number` — exact line of failure
64+
- `failures[].issue_type`type of issue (assertion_failure, etc.)
65+
- `repetitions`if present, shows retry behavior (pass/fail sequence)
66+
- `test_run_id` — the broader test run this execution belongs to
67+
68+
## Code Analysis
69+
70+
1. Open the file at `failures[0].path` and go to `failures[0].line_number`.
71+
2. Read the full test function and its setup/teardown.
72+
3. Identify which of the common flaky patterns below applies.
73+
4. Check if the test shares state with other tests in the same suite.
74+
75+
## Common Flaky Patterns
76+
77+
### Timing and async issues
78+
- **Missing waits**: Test checks a result before an async operation completes. Fix: use `await`, expectations with timeouts, or polling.
79+
- **Race conditions**: Multiple concurrent operations access shared state. Fix: synchronize access or use serial queues.
80+
- **Hardcoded timeouts**: `sleep(1)` or fixed delays that are too short on CI. Fix: use condition-based waits instead of fixed delays.
81+
82+
### Shared state
83+
- **Test pollution**: One test modifies global/static state that another test depends on. Fix: reset state in setUp/tearDown or use unique instances per test.
84+
- **Singleton contamination**: Shared singletons carry state between tests. Fix: inject dependencies or reset singletons.
85+
- **File system leftovers**: Tests leave files that affect subsequent runs. Fix: use temporary directories and clean up.
86+
87+
### Environment dependencies
88+
- **Network calls**: Tests hit real services that may be slow or unavailable. Fix: mock network calls.
89+
- **Date/time sensitivity**: Tests depend on current time or timezone. Fix: inject a clock or freeze time.
90+
- **File system paths**: Hardcoded paths that differ between environments. Fix: use relative paths or temp directories.
91+
92+
### Order dependence
93+
- **Implicit ordering**: Test passes only when run after another test that sets up required state. Fix: make each test self-contained.
94+
- **Parallel execution conflicts**: Tests that work in isolation but fail when run concurrently. Fix: use unique resources per test.
95+
96+
## Fix Implementation
97+
98+
After identifying the pattern:
99+
100+
1. Apply the smallest fix that addresses the root cause.
101+
2. Do not refactor unrelated code.
102+
3. If the fix requires a test utility (like a mock or helper), check if one already exists before creating a new one.
103+
104+
## Verification
105+
106+
Run the specific test repeatedly until failure using `xcodebuild`'s built-in repetition support:
107+
108+
```bash
109+
xcodebuild test -workspace <workspace> -scheme <scheme> -only-testing <module>/<suite>/<test> -test-iterations <count> -run-tests-until-failure
110+
```
111+
112+
This runs the test up to `<count>` times and stops at the first failure. Choose the iteration count based on how long the test takes — for fast unit tests use 50–100, for slower integration or acceptance tests use 2–5.
113+
114+
## Done Checklist
115+
116+
- Identified the root cause of flakiness
117+
- Applied a targeted fix
118+
- Verified the test passes consistently (multiple runs)
119+
- Did not introduce new test dependencies or shared state
120+
- Committed the fix with a descriptive message

0 commit comments

Comments
 (0)