본문으로 건너뛰기
cccskills
무료GitHub에 공개

tdd:ci

CI-driven TDD workflow - commit, local checks, push, wait for CI, iterate on failures

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rossoctl/rossoctl스타 303(GitHub 303 + cccskills 0)

실행 점수 미검증

설치 방법 보기

포함된 파일(2)

  • SKILL.md19.9 KB
  • tdd-ci-workflow.mmd1.3 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

TDD-CI Workflow

Table of Contents

Iterative development workflow using CI as the test environment. Commit changes, run local checks, push to PR, wait for CI results, and iterate on failures.

Context-Safe Execution (MANDATORY)

Every command that produces more than ~5 lines of output MUST redirect to a file.

# Session-scoped log directory — use worktree/repo name to avoid collisions
# For parallel worktree sessions, pre-set LOG_DIR to a unique path
export LOG_DIR="${LOG_DIR:-${WORKSPACE_DIR:-/tmp}/rossoctl-tdd}"
mkdir -p "$LOG_DIR"

Key Patterns

# CI log download — ALWAYS to file, NEVER into context
gh run view <run-id> --log-failed > $LOG_DIR/ci-failed.log 2>&1; echo "EXIT:$?"
# Analyze failures in subagent: Task(subagent_type='Explore') to read $LOG_DIR/ci-failed.log

# Local checks — redirect output
make lint > $LOG_DIR/lint.log 2>&1 && echo "OK: lint passed" || echo "FAIL (see $LOG_DIR/lint.log)"
pre-commit run --all-files > $LOG_DIR/precommit.log 2>&1 && echo "OK: pre-commit passed" || echo "FAIL (see $LOG_DIR/precommit.log)"
uv run pytest rossoctl/tests/ -v --ignore=rossoctl/tests/e2e > $LOG_DIR/unit-tests.log 2>&1 && echo "OK: tests passed" || echo "FAIL (see $LOG_DIR/unit-tests.log)"

Log Analysis Rule

NEVER read large log files in the main context. Always use subagents:

  1. Note the log file path and exit code
  2. Use Task(subagent_type='Explore') to read the log and extract relevant info
  3. The subagent returns a concise summary (errors, unexpected output, specific data)
  4. Use subagents for success analysis too — e.g., "verify lint passed with no warnings"
  5. Fix or proceed based on the summary

tdd:ci vs tdd:hypershift

Aspecttdd:citdd:hypershift
Test environmentCI pipeline (no direct access)Your own HyperShift cluster
DebuggingAnalyze CI logs after failureReal-time debugging with k8s:* skills
Feedback loopSlower (wait for CI)Faster (immediate cluster access)
Use whenFinal validation, no clusterActive development, need to inspect state

Use tdd:hypershift when you have a cluster and need real-time debugging. Use tdd:ci when iterating on CI failures or for final PR validation.

When to Use

  • Iterating on CI failures (no cluster access needed)
  • Final validation before merge
  • When you don't have a HyperShift cluster running
  • Simple changes that don't need live debugging

The Workflow

flowchart TD
    START(["/tdd:ci"]) --> HAS_URL{"Has GH URL?"}
    HAS_URL -->|Yes| P0["Phase 0: Worktree Setup"]:::tdd
    HAS_URL -->|No| P1

    P0 --> IS_ISSUE{"Is issue URL?"}
    IS_ISSUE -->|Yes| P0B["Phase 0b: Research & Plan"]:::tdd
    IS_ISSUE -->|No, PR| P1

    P0B --> P1["Phase 1: Brainstorm"]:::tdd
    P1 --> P2["Phase 2: Commit"]:::git
    P2 --> P3["Phase 3: Local Checks"]:::test
    P3 -->|Checks fail| P2
    P3 -->|Checks pass| P3B["Phase 3.5: CVE Gate"]:::cve
    P3B -->|Clean| P4["Phase 4: Push to PR"]:::git
    P3B -->|CVE found| CVE_HOLD["cve:brainstorm (BLOCKS push)"]:::cve
    CVE_HOLD -->|Resolved| P4
    P4 --> P5["Phase 5: Wait for CI"]:::ci
    P5 --> RESULT{"CI Result?"}

    RESULT -->|Pass| P8["Phase 8: Handle Reviews"]:::tdd
    RESULT -->|Fail| P6["Phase 6: Analyze Failures"]:::rca

    P6 --> FAILCOUNT{"3+ failures?"}
    FAILCOUNT -->|No| P7["Phase 7: Fix & Iterate"]:::tdd
    FAILCOUNT -->|Yes| ESCALATE["Escalate to tdd:hypershift"]:::hypershift

    P7 --> P2

    P8 -->|Changes needed| P2
    P8 -->|Approved| DONE([Merged])

    ESCALATE --> HS["tdd:hypershift"]:::tdd

    classDef tdd fill:#4CAF50,stroke:#333,color:white
    classDef rca fill:#FF5722,stroke:#333,color:white
    classDef git fill:#FF9800,stroke:#333,color:white
    classDef k8s fill:#00BCD4,stroke:#333,color:white
    classDef hypershift fill:#3F51B5,stroke:#333,color:white
    classDef ci fill:#2196F3,stroke:#333,color:white
    classDef test fill:#9C27B0,stroke:#333,color:white
    classDef cve fill:#D32F2F,stroke:#333,color:white

Follow this diagram as the workflow.

Phase 0: Worktree Setup (when linked to GH issue/PR)

This phase is MANDATORY when tdd:ci is invoked with a GitHub issue or PR URL.

When the skill receives a GitHub URL (issue or PR), the first step is always to set up an isolated worktree based on upstream/main. This ensures the fix is developed against the latest upstream code, not against a local feature branch.

Steps

  1. Parse the issue/PR from the URL argument:

    • Extract repo owner/name and issue/PR number
    • Fetch the issue/PR details with gh issue view or gh pr view
  2. Fetch upstream main:

    git fetch upstream main
    
  3. Check for existing worktree for this issue/PR:

    git worktree list
    

    Look for branches containing the issue number (e.g. fix/keycloak-login-652).

  4. If no worktree exists, ask the user for a worktree name (suggest a default based on the issue, e.g. fix-652), then create it:

    git worktree add .worktrees/<name> -b fix/<slug>-<number> upstream/main
    
  5. If a worktree already exists, confirm with the user whether to reuse it.

  6. All subsequent phases operate inside the worktree. File reads, edits, commits, and pushes all happen under .worktrees/<name>/.

Branch naming convention

  • Issues: fix/<slug>-<number> (e.g. fix/keycloak-login-652)
  • PRs: reuse the existing PR branch

Example: Clear fix

/tdd:ci https://github.com/rossoctl/rossoctl/issues/652

-> Fetch upstream main
-> No existing worktree for #652
-> Ask user: "Worktree name?" (default: fix-652)
-> git worktree add .worktrees/fix-652 -b fix/keycloak-login-652 upstream/main
-> Phase 0b: Research codebase, find root cause
-> Post to issue: "Root cause is X. I'll fix by Y. Creating PR."
-> Implement fix in .worktrees/fix-652/
-> Commit, push, create PR against upstream/main

Example: Unclear approach — post questions and wait

/tdd:ci https://github.com/rossoctl/rossoctl/issues/678

-> Fetch upstream main, create worktree
-> Phase 0b: Research reveals two possible causes
-> Post to issue:
     "## Investigation
      I found two potential root causes:
      1. Keycloak redirect URL mismatch — backend uses external URL for JWKS
      2. Role mapping — admin role not mapped to rossoctl-admin

      ## Questions
      - Should the backend use an in-cluster URL for JWKS, or fix DNS?
      - Is the admin→rossoctl-admin role mapping intentional?

      Waiting for clarification before proceeding."
-> STOP — wait for issue author to respond
-> (Author replies: "Option 1 for JWKS, role mapping is a bug")
-> Resume: implement fix based on response
-> Commit, push, create PR

Example: Multiple approaches — present options

/tdd:ci https://github.com/rossoctl/rossoctl/issues/700

-> Research reveals the fix can go two ways
-> Post to issue:
     "## Proposed approaches
      1. **Add KEYCLOAK_INTERNAL_URL env var** — explicit, works everywhere,
         but adds configuration surface
      2. **Auto-detect in-cluster via KUBERNETES_SERVICE_HOST** — zero config,
         but implicit and harder to debug

      Which approach do you prefer?"
-> STOP — wait for response before coding

Phase 0b: Research & Plan (when working from a GH issue)

This phase applies to ALL /tdd skills when invoked with a GH issue URL. Before writing any code, investigate the issue and present findings.

Steps

  1. Read the issue — understand what's reported, what's expected, reproduction steps

  2. Research — investigate the codebase for the root cause:

    • Use rca:ci or rca:kind patterns to diagnose
    • Search for the affected component, trace the code path
    • Check if tests exist for this scenario
  3. Plan the fix — determine the approach:

    • What files need to change
    • What tests need to be written or updated
    • Are there multiple valid approaches?
  4. Post to the issue — before coding, comment on the issue (requires approval):

    ## Investigation
    
    **Root cause**: [what causes the issue]
    **Affected files**: [list]
    
    ## Proposed approach
    
    [If clear approach]: "I plan to fix this by [description]. Will create a PR."
    
    [If multiple options]:
    "I see two approaches:
     1. [approach A] — [tradeoff]
     2. [approach B] — [tradeoff]
     Which approach do you prefer?"
    
    [If unclear]: "I have questions about this issue:
     - [question 1]
     - [question 2]"
    
  5. Wait for response if questions were posted. Proceed with coding if the approach is clear.

Phase 1: Brainstorm (New Features)

For new features or complex changes, use the brainstorming skill first:

/superpowers:brainstorming

This helps clarify:

  • What exactly needs to be done
  • Edge cases and requirements
  • Potential approaches

Phase 2: Commit

Branch verification (first commit only)

Before the first commit, run the Branch Verification Gate (see parent tdd skill):

git branch --show-current
gh pr list --head "$(git branch --show-current)" --json number,title,url --jq '.[] | "#\(.number) \(.title) \(.url)"'

If the current branch has an open PR for different work, stop and create a worktree:

git worktree add .worktrees/<name> -b <new-branch> upstream/main

Create commit

Create a focused commit with your changes:

# Stage specific files (not git add -A)
git add <changed-files>

# Commit with sign-off
git commit -s -m "fix: description of change"

Commit message conventions:

  • fix: - Bug fixes
  • feat: - New features
  • docs: - Documentation
  • refactor: - Code refactoring
  • test: - Test changes
  • chore: - Maintenance

Phase 3: Local Checks

Run local validation before pushing (redirect output to files):

make lint > $LOG_DIR/lint.log 2>&1 && echo "OK: lint" || echo "FAIL: lint (see $LOG_DIR/lint.log)"
pre-commit run --all-files > $LOG_DIR/precommit.log 2>&1 && echo "OK: pre-commit" || echo "FAIL: pre-commit (see $LOG_DIR/precommit.log)"
uv run pytest rossoctl/tests/ -v --ignore=rossoctl/tests/e2e > $LOG_DIR/unit-tests.log 2>&1 && echo "OK: tests" || echo "FAIL: tests (see $LOG_DIR/unit-tests.log)"

Fix any failures before pushing. On failure, use Task(subagent_type='Explore') to read the log file.

Phase 3.5: CVE Gate

MANDATORY before pushing. Scan dependencies for known CVEs before any public output.

Invoke cve:scan on the working tree:

  1. If cve:scan returns clean → proceed to Phase 4
  2. If cve:scan finds HIGH/CRITICAL CVEs → cve:brainstorm activates a CVE hold
    • Do NOT proceed to Phase 4 until the hold is resolved
    • The hold blocks gh pr create, gh pr comment, gh issue create/comment
    • Silent fixes (dependency bumps with neutral commit messages) are allowed
    • See cve:brainstorm for resolution steps

Phase 4: Push to PR

# Push to remote (creates PR if needed)
git push -u origin <branch-name>

# Or if PR exists, just push
git push

If no PR exists yet:

gh pr create --title "fix: description" --body "## Summary
- What this changes

## Test plan
- CI will validate"

Phase 5: Wait for CI

Monitor CI status:

# Watch PR checks
gh pr checks --watch

# Or check specific workflow
gh run list --branch <branch-name>
gh run view <run-id>

Wait for CI to complete before making more changes.

Phase 6: Analyze Failures

When CI fails, download logs to a file — never dump CI logs into main context:

# Download failed run logs to file
gh run view <run-id> --log-failed > $LOG_DIR/ci-run-<run-id>.log 2>&1; echo "EXIT:$?"

# Or view in browser (minimal context — just prints URL)
gh run view <run-id> --web

Analyze in subagent — use Task(subagent_type='Explore') to read $LOG_DIR/ci-run-<run-id>.log and:

  1. Find the first error
  2. Check if it's a flaky test or real failure
  3. Return a 1-3 line summary of root cause
  4. Use superpowers:systematic-debugging for complex failures

Phase 7: Fix and Iterate

# Make fix
vim <file>

# Commit the fix (new commit, not amend)
git add <fixed-files>
git commit -s -m "fix: address CI failure - description"

# Push
git push

# Wait for CI again
gh pr checks --watch

Repeat until all checks pass.

Phase 8: Handle PR Reviews (after CI passes)

When CI passes, check for review comments:

gh pr view <pr-number> --json reviews,comments --jq '.reviews[] | "\(.author.login): \(.state) - \(.body[:100])"'
gh api repos/rossoctl/rossoctl/pulls/<pr-number>/comments --jq '.[] | "#\(.id) @\(.user.login) [\(.path):\(.line)] \(.body[:100])"'

For each review comment, determine:

Review comment received
    │
    ├─ Clear actionable feedback → Implement as a NEW commit
    │   (one commit per logical review item, not one per comment)
    │
    ├─ Ambiguous or unclear → Comment back on the PR asking
    │   for clarification with specific questions
    │
    ├─ Disagree with suggestion → Comment back explaining why,
    │   offer alternative approach with evidence
    │
    └─ Multiple options possible → Comment with options:
        "I see two approaches for this:
         1. [approach A] — [tradeoff]
         2. [approach B] — [tradeoff]
         Which do you prefer?"

Commit review fixes

Each logical review item gets its own commit:

git add <files>
git commit -s -m "fix: address review - <what changed>"

After addressing all comments, push and comment on the PR:

git push

Then summarize what was addressed in a PR comment (requires approval):

Addressed review feedback:
- commit abc123: [what was changed for comment X]
- commit def456: [what was changed for comment Y]
- Replied to comment Z with question about [topic]

Then wait for CI again (back to Phase 5)

After pushing review fixes, wait for CI to pass, then check for new review comments. Repeat until approved.

Escalation: Too Many Iterations?

After 3+ failed CI iterations, consider switching to tdd:hypershift for real-time debugging:

Check for Existing Cluster

# Check if cluster exists for current worktree
WORKTREE=$(basename "${WORKSPACE_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}")
ls ~/clusters/hcp/rossoctl-hypershift-custom-*/auth/kubeconfig 2>/dev/null

Decision Tree

CI failed 3+ times?
    │
    ├─ YES → Check for existing cluster
    │         │
    │         ├─ Cluster exists → Switch to `tdd:hypershift`
    │         │
    │         └─ No cluster → Ask user:
    │                         "Create HyperShift cluster for debugging?"
    │                         │
    │                         ├─ YES → Use `hypershift:cluster` to create
    │                         │        Then switch to `tdd:hypershift`
    │                         │
    │                         └─ NO → Continue with tdd:ci
    │
    └─ NO → Continue iterating

Escalate to HyperShift

If user approves cluster creation:

# Create cluster (max 5 char suffix)
KUBECONFIG=~/clusters/hcp/rossoctl-hypershift-custom-<suffix>/auth/kubeconfig \
  ./.github/scripts/local-setup/hypershift-full-test.sh <suffix> \
  --include-cluster-create --skip-cluster-destroy

Then switch to tdd:hypershift for real-time debugging with:

  • k8s:pods - inspect pod state
  • k8s:logs - check logs immediately
  • k8s:live-debugging - iterative fixes

Quick Reference

StepCommand
Stage filesgit add <files>
Commitgit commit -s -m "type: message"
Lintmake lint
Pre-commitpre-commit run --all-files
Pushgit push
Watch CIgh pr checks --watch
View failuregh run view <id> --log-failed

Task Tracking

On invocation:

  1. TaskList - check existing tasks for this worktree/issue
  2. TaskCreate with naming convention:
    • <worktree> | <PR> | <plan-doc> | <topic> | <phase> | <task>
    • Example: fix-652 | PR#656 | ad-hoc | Keycloak login | Phase 0 | Create worktree
    • Example: fix-652 | PR#656 | ad-hoc | Keycloak login | Phase 2 | Commit fix
  3. TaskUpdate as each phase completes

Typical task structure for an issue fix:

#1 [completed] fix-652 | none | ad-hoc | Keycloak | Phase 0 | Create worktree
#2 [completed] fix-652 | none | ad-hoc | Keycloak | Investigate | Root cause analysis
#3 [completed] fix-652 | PR#656 | ad-hoc | Keycloak | Phase 2 | Commit fix
#4 [completed] fix-652 | PR#656 | ad-hoc | Keycloak | Phase 4 | Push and create PR
#5 [completed] fix-652 | PR#656 | ad-hoc | Keycloak | Phase 5 | Wait for CI

Anti-Patterns

Don'tDo Instead
Commit to a branch with an unrelated open PRRun branch verification gate, create worktree
Work on current branch when given an issue URLCreate a worktree from upstream/main
Push without local checksRun make lint and pre-commit first
Amend after pushCreate new commits
Push multiple times quicklyWait for CI between pushes
Guess at fixesAnalyze failure logs first
Skip brainstormingUse /superpowers:brainstorming for new features

Troubleshooting

Problem: Worktree branch already exists

Symptom: git worktree add fails with "branch already exists" Fix: Check if worktree already exists with git worktree list. Reuse it or remove with git worktree remove.

Problem: Helm dependency build needed in worktree

Symptom: helm template fails with missing dependencies Fix: Run helm dependency build in the worktree's chart directory.

Problem: CI fails on DCO check

Symptom: DCO check fails on PR Fix: Ensure commits use git commit -s for sign-off.

UI Tests

For Playwright UI tests (login, navigation, agent chat), invoke test:ui. CI runs UI tests automatically via 91-run-ui-tests.sh after pytest E2E tests.

Session Reporting

After the TDD workflow completes (CI green and PR approved/merged), invoke session:post to capture session metadata:

  1. The skill auto-detects the current session ID and PR number
  2. Posts a session report comment with token usage, skills used, and workflow diagram
  3. Updates the pinned summary comment

This is optional but recommended for tracking development effort.

Related Skills

  • test:ui - Write and run Playwright UI tests (CI/Kind/HyperShift)
  • git:worktree - Create and manage git worktrees
  • superpowers:brainstorming - Design before implementation
  • superpowers:systematic-debugging - Debug CI failures
  • superpowers:verification-before-completion - Verify before claiming done
  • tdd:hypershift - TDD with HyperShift clusters
  • git:status - Check worktree and PR status before pushing
  • test:review - Review test quality
  • test:write - Write new tests
  • git:commit - Commit format and conventions
  • git:rebase - Rebase onto upstream main
  • session:post - Post session analytics to PR
  • cve:scan - CVE scanning gate (Phase 3.5)
  • cve:brainstorm - CVE disclosure planning (if CVEs found)

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

auth

무료

Authentication and authorization patterns for Rossoctl services

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rossoctl/rossoctl3032026년 10월 25일 업데이트

Create confidential OAuth2 clients in Keycloak for server-to-service authentication

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rossoctl/rossoctl3032026년 10월 25일 업데이트

Configure MLflow with mlflow-oidc-auth plugin for Keycloak OIDC authentication

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rossoctl/rossoctl3032026년 10월 25일 업데이트

Configure OpenTelemetry Collector with OAuth2 authentication for trace export

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rossoctl/rossoctl3032026년 10월 25일 업데이트

ci

무료

CI pipeline monitoring, status checks, and PR validation workflows

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rossoctl/rossoctl3032026년 10월 25일 업데이트

Monitor running CI jobs, wait for completion, create tasks for results

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

rossoctl/rossoctl3032026년 10월 25일 업데이트

rossoctl의 스킬 모두 보기

이 스킬의 문제 신고