Lab — Copilot custom agent + plan-then-act + branch protection
Lab — Copilot custom agent + plan-then-act + branch protection
Bu derste neler öğreneceksin
- Bir test repo'sunda Copilot custom agent tanımlamayı uygulamak
- Custom instructions ile structured plan output'u zorunlu kılmak
- Plan validation workflow'u kurmak (schema + policy)
- Branch protection ile 'plan onaylanmadan merge yok' kapısını kapatmak
Tahmini süre: 30 dakika. Sınav Türü değil — uygulamalı lab. Bunu yapmak Domain 1’in tüm bullet’larını birden ezberletir.
Ön koşul
- GitHub hesabı (kişisel veya organization)
- Copilot subscription (custom agent için)
- Git ve
ghCLI kurulu - Bu kursun Modül 1’i bitmiş olmalı (GitHub temelleri biliniyor)
Adım 1: Test repo oluştur (3 dk)
gh repo create gh600-d1-lab --public --clone
cd gh600-d1-lab
echo "# GH-600 Domain 1 Lab" > README.md
git add README.md
git commit -m "init"
git push -u origin main
Adım 2: Custom instructions yaz (5 dk)
mkdir -p .github
cat > .github/copilot-instructions.md <<'EOF'
# Copilot custom instructions for this repo
## Mandatory plan output
Before executing ANY task that changes more than 1 file or affects code
behavior, you MUST first output a structured plan in the PR description
using this YAML schema:
```yaml
plan:
goal: <one-sentence goal>
inputs:
- <input 1>
steps:
- id: 1
action: <verb-first action>
expected_output: <verifiable result>
success_criteria: <verifiable criterion>
risks:
- <risk 1>
mitigations:
- <mitigation 1>
abort_conditions:
- <abort condition 1>
Do NOT execute any step until:
- The PR is opened with the plan in the description
- The
plan-validationcheck is green - At least 1 reviewer has approved EOF git add .github/copilot-instructions.md git commit -m “feat: copilot instructions for plan-then-act” git push
## Adım 3: Plan validation workflow (10 dk)
```bash
mkdir -p .github/workflows
cat > .github/workflows/plan-validation.yml <<'EOF'
name: plan-validation
on:
pull_request:
types: [opened, edited, synchronize]
permissions:
contents: read
pull-requests: read
jobs:
validate-plan:
runs-on: ubuntu-latest
steps:
- name: Install yq
run: |
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
sudo chmod +x /usr/local/bin/yq
- name: Extract plan from PR body
env:
PR_BODY: ${{ github.event.pull_request.body }}
run: |
# PR body içinde ```yaml ... ``` bloğu bekle
echo "$PR_BODY" | sed -n '/```yaml/,/```/p' | sed '1d;$d' > plan.yaml
if [ ! -s plan.yaml ]; then
echo "::error::No YAML plan found in PR body."
exit 1
fi
cat plan.yaml
- name: Validate schema
run: |
yq -e '.plan.goal and .plan.steps and .plan.success_criteria' plan.yaml
echo "✓ Required fields present"
- name: Policy check (forbidden actions)
run: |
if grep -iE "rm -rf|drop table|force.push|--no-verify" plan.yaml; then
echo "::error::Policy violation: forbidden action in plan"
exit 1
fi
echo "✓ No forbidden actions"
- name: Plan size sanity
run: |
steps=$(yq '.plan.steps | length' plan.yaml)
if [ "$steps" -gt 20 ]; then
echo "::error::Plan has $steps steps; consider splitting (max 20)"
exit 1
fi
echo "✓ Plan has $steps steps"
EOF
git add .github/workflows/plan-validation.yml
git commit -m "ci: plan-validation workflow"
git push
Adım 4: Branch protection (5 dk)
gh api -X PUT "repos/{owner}/gh600-d1-lab/branches/main/protection" \
-F required_status_checks.strict=true \
-F required_status_checks.contexts[]=validate-plan \
-F enforce_admins=false \
-F required_pull_request_reviews.required_approving_review_count=1 \
-F restrictions=null
Eğer organization repo’sundaysan
{owner}yerine org adı; kişisel ise GitHub username.
GUI’den de yapılabilir: Settings → Branches → Add branch protection rule
→ Branch name: main, Tikla: “Require a pull request”, “Require approvals” (1),
“Require status checks” → validate-plan ekle.
Adım 5: Test et (7 dk)
git checkout -b test/plan-then-act
# Bilinçli olarak plan'sız değişiklik
echo "test" > test.md
git add test.md
git commit -m "feat: add test file"
git push -u origin test/plan-then-act
# PR aç plan'sız
gh pr create --title "test plan-then-act" --body "Just a test file, no plan"
PR check’leri başlar. plan-validation fail olur (no YAML plan).
Branch protection merge’i engeller. ✓
Şimdi PR description’ı güncelle:
gh pr edit --body "$(cat <<'EOF'
Adding a test file for plan-then-act validation.
```yaml
plan:
goal: "Add a test.md file to validate plan-then-act workflow"
inputs:
- "Empty test.md created via shell"
steps:
- id: 1
action: "Create test.md"
expected_output: "File exists in repo root"
success_criteria: "PR check `validate-plan` is green and reviewer approves"
risks:
- "None significant"
mitigations:
- "File is trivial, no functional impact"
abort_conditions:
- "Plan validation fails"
EOF )”
Şimdi `validate-plan` ✓ olur, ama hâlâ 1 approval gerekli (branch
protection).
Eğer test repo'sunda ek hesap yoksa branch protection'da
`required_approving_review_count=0` yapabilirsin ya da geçici olarak
kapatabilirsin — lab amaçlı yeterli.
## Adım 6: Forbidden action ile policy check'i tetikle (opsiyonel)
```bash
gh pr edit --body "$(cat <<'EOF'
Test forbidden action
```yaml
plan:
goal: "DROP TABLE users to test policy check"
inputs: ["db"]
steps:
- id: 1
action: "DROP TABLE users"
expected_output: "table dropped"
success_criteria: "table dropped"
risks: ["data loss"]
mitigations: ["backup"]
abort_conditions: ["fail"]
EOF )”
`validate-plan` ✗ olur (policy violation: `DROP TABLE`). ✓ Policy check
çalışıyor.
## Lab özeti — neyi öğrendin?
Bu lab Domain 1'in 4 bullet'ını birden uygular:
| Bullet | Lab adımı |
|--------|-----------|
| `d1-sdlc-define-criteria` (success criteria) | Plan şemasında `success_criteria` zorunlu |
| `d1-boundaries-structured-plan` | YAML şema + alanlar |
| `d1-boundaries-validate-plan` | `validate-plan` workflow'u (schema + policy) |
| `d1-boundaries-block-until-approved` | Branch protection required reviewer + status check |
| `d1-observability-inspectable-artifacts` | PR description ve workflow logs |
Bu pattern senin gerçek projende de uygulanabilir — sadece copilot
instructions ve workflow dosyasını uyarlaman gerekir.
## Lab'ı bitirdikten sonra
Test repo'sunu silmek istiyorsan:
```bash
gh repo delete gh600-d1-lab --confirm
Veya gelecekte referans olarak saklayabilirsin.
Sırada ne var?
Domain 2 — Tool & MCP modülüne geçiyoruz. En ağır domain (%20-25), 6 ders. Lab + sandbox + community pattern’leri burada yoğun.