Files
gitea/docs/testing-guide-v1.26.md
logikonline b8b276fa05
Some checks failed
Build and Release / Lint and Test (push) Successful in 4m46s
Build and Release / Build Binaries (amd64, linux) (push) Failing after 42s
Build and Release / Build Binaries (amd64, darwin) (push) Has been cancelled
Build and Release / Build Binaries (amd64, windows) (push) Has been cancelled
Build and Release / Build Binaries (arm64, darwin) (push) Has been cancelled
Build and Release / Create Release (push) Has been cancelled
Build and Release / Build Binaries (arm64, linux) (push) Has been cancelled
Build and Release / Build Docker Image (push) Has been cancelled
docs: comprehensive testing guide covering all 5 phases
Updated testing guide now covers:

Phase 1: API Reliability
- Request ID tracing
- Rate limit headers
- Chunk checksum verification
- RFC 7807 error responses

Phase 2: V2 API
- V2 framework
- Scalar docs
- Batch operations
- NDJSON streaming
- AI context endpoints

Phase 3: Reliability Patterns
- Operation progress (SSE)
- Idempotency middleware
- Webhook retry
- Circuit breaker

Phase 4: SDK & CLI
- gitea-cli tool
- Go, Python, TypeScript, C#, Java SDKs

Phase 5: New Features
- Organization pinned repos
- Public members
- Gitea Pages (4 templates)
- Wiki V2 API

Also includes:
- Complete smoke test script
- Regression testing checklist
- Rollback plan

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 15:24:40 -05:00

1010 lines
25 KiB
Markdown

# Comprehensive Testing Guide for Gitea v1.26.0
## All Features to Test
| Phase | Feature | Risk | Priority |
|-------|---------|------|----------|
| **1** | Request ID Tracing | Low | Medium |
| **1** | Rate Limit Headers | Low | Medium |
| **1** | Chunk Checksum Verification | Medium | High |
| **1** | RFC 7807 Error Responses | Low | Medium |
| **2** | V2 API Framework | Medium | High |
| **2** | Structured Error Codes | Low | Medium |
| **2** | Scalar API Docs | Low | Low |
| **2** | Batch Operations | Medium | High |
| **2** | NDJSON Streaming | Medium | High |
| **2** | AI Context Endpoints | Low | Medium |
| **3** | Operation Progress (SSE) | Medium | High |
| **3** | Idempotency Middleware | High | Critical |
| **3** | Webhook Retry | Medium | High |
| **3** | Circuit Breaker | Medium | High |
| **4** | CLI Tool (gitea-cli) | Low | Medium |
| **4** | Go SDK | Low | Medium |
| **4** | Python SDK | Low | Medium |
| **4** | TypeScript SDK | Low | Medium |
| **4** | C# SDK | Low | Medium |
| **4** | Java SDK | Low | Medium |
| **5** | Organization Pinned Repos | Low | Medium |
| **5** | Organization Public Members | Low | Medium |
| **5** | Gitea Pages | Medium | High |
| **5** | Wiki V2 API | Medium | High |
---
## 1. Test Environment Setup
### Docker Test Instance
```bash
mkdir gitea-test && cd gitea-test
cat > docker-compose.yml << 'EOF'
version: "3"
services:
gitea:
image: gitea/gitea:1.26.0
container_name: gitea-test
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=sqlite3
- GITEA__server__ROOT_URL=http://localhost:3000/
volumes:
- ./gitea-data:/data
ports:
- "3000:3000"
- "2222:22"
EOF
docker-compose up -d
```
---
## 2. Phase 1: API Reliability Enhancements
### 2.1 Request ID Tracing
```bash
# Test auto-generated request ID
curl -i http://localhost:3000/api/v1/version
# Should see: X-Request-ID: <short-uuid>
# Test custom request ID passed through
curl -i -H "X-Request-ID: my-custom-id-123" http://localhost:3000/api/v1/version
# Should see: X-Request-ID: my-custom-id-123
# Test request ID in error responses
curl -i http://localhost:3000/api/v1/repos/nonexistent/nonexistent
# Error JSON should contain request_id field
```
**Checklist:**
- [ ] X-Request-ID header present in all responses
- [ ] Custom X-Request-ID passed through unchanged
- [ ] Request ID included in error response body
- [ ] Request ID appears in server logs
### 2.2 Rate Limit Headers
```bash
# Check rate limit headers
curl -i -H "Authorization: token $TOKEN" http://localhost:3000/api/v1/user
# Should see:
# X-RateLimit-Limit: <configured limit>
# X-RateLimit-Remaining: <remaining>
# X-RateLimit-Reset: <unix timestamp>
```
**Checklist:**
- [ ] Rate limit headers present on authenticated requests
- [ ] Remaining count decrements
- [ ] Reset timestamp is in the future
### 2.3 Chunk Checksum Verification
```bash
# Create a test file
echo "test content" > testfile.txt
CHECKSUM=$(sha256sum testfile.txt | cut -d' ' -f1)
# Upload with correct checksum (should succeed)
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "X-Chunk-Checksum: sha256=$CHECKSUM" \
-F "file=@testfile.txt" \
"http://localhost:3000/api/v1/repos/owner/repo/releases/1/assets"
# Upload with wrong checksum (should fail)
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "X-Chunk-Checksum: sha256=wrongchecksum123" \
-F "file=@testfile.txt" \
"http://localhost:3000/api/v1/repos/owner/repo/releases/1/assets"
# Should return 400 with checksum mismatch error
```
**Checklist:**
- [ ] Upload succeeds with correct checksum
- [ ] Upload fails with incorrect checksum
- [ ] Upload succeeds without checksum header (optional)
- [ ] Error message indicates checksum mismatch
### 2.4 RFC 7807 Error Responses
```bash
# Trigger a 404 error
curl -s http://localhost:3000/api/v1/repos/nonexistent/nonexistent | jq .
```
**Expected Response:**
```json
{
"type": "https://gitea.io/api/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "Repository not found",
"instance": "/api/v1/repos/nonexistent/nonexistent",
"request_id": "abc123",
"message": "Repository not found",
"url": "https://gitea.io/api/errors/not-found"
}
```
**Checklist:**
- [ ] Error responses include `type`, `title`, `status`, `detail`
- [ ] Legacy fields (`message`, `url`) still present for compatibility
- [ ] `request_id` included in errors
---
## 3. Phase 2: V2 API with AI Features
### 3.1 V2 API Framework
```bash
# Test v2 version endpoint
curl http://localhost:3000/api/v2/version
# Test v2 user endpoint (requires auth)
curl -H "Authorization: token $TOKEN" http://localhost:3000/api/v2/user
```
**Checklist:**
- [ ] V2 endpoints respond at `/api/v2/`
- [ ] V1 endpoints still work at `/api/v1/`
- [ ] Authentication works on v2
### 3.2 Scalar API Documentation
```bash
# Open in browser
open http://localhost:3000/api/v2/docs
# Fetch OpenAPI spec
curl http://localhost:3000/api/v2/swagger.json
```
**Checklist:**
- [ ] Scalar docs page loads
- [ ] All v2 endpoints documented
- [ ] "Try it" functionality works
### 3.3 Batch Operations
```bash
# Batch get files
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requests": [
{"owner": "org", "repo": "repo1", "path": "README.md", "ref": "main"},
{"owner": "org", "repo": "repo1", "path": "go.mod", "ref": "main"},
{"owner": "org", "repo": "repo2", "path": "package.json", "ref": "main"}
]
}' \
http://localhost:3000/api/v2/batch/files
# Batch get repos
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"repos": [
{"owner": "org", "repo": "repo1"},
{"owner": "org", "repo": "repo2"},
{"owner": "org", "repo": "repo3"}
]
}' \
http://localhost:3000/api/v2/batch/repos
```
**Checklist:**
- [ ] Batch files returns multiple file contents
- [ ] Batch repos returns multiple repo details
- [ ] Partial failures handled gracefully (some succeed, some fail)
- [ ] Performance better than individual requests
### 3.4 NDJSON Streaming
```bash
# Stream files
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/x-ndjson" \
-d '{"owner": "org", "repo": "repo", "paths": ["file1.go", "file2.go"]}' \
http://localhost:3000/api/v2/stream/files
# Stream commits
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/x-ndjson" \
-d '{"owner": "org", "repo": "repo", "ref": "main", "limit": 100}' \
http://localhost:3000/api/v2/stream/commits
# Stream issues
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/x-ndjson" \
-d '{"owner": "org", "repo": "repo", "state": "open"}' \
http://localhost:3000/api/v2/stream/issues
```
**Checklist:**
- [ ] Responses are newline-delimited JSON
- [ ] Each line is valid JSON
- [ ] Streaming starts before all data is ready
- [ ] Large datasets don't timeout
### 3.5 AI Context Endpoints
```bash
# Repository summary
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"owner": "org", "repo": "repo"}' \
http://localhost:3000/api/v2/ai/repo/summary
# Navigation hints
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"owner": "org", "repo": "repo"}' \
http://localhost:3000/api/v2/ai/repo/navigation
# Issue context
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"owner": "org", "repo": "repo", "issue_number": 1}' \
http://localhost:3000/api/v2/ai/issue/context
```
**Checklist:**
- [ ] Repo summary includes structure, languages, recent activity
- [ ] Navigation includes important paths, file types
- [ ] Issue context includes comments, labels, code references
- [ ] AI hints provided (project type, suggested files)
---
## 4. Phase 3: Reliability Patterns
### 4.1 Operation Progress (SSE)
```bash
# Start a long operation that returns operation ID
OPERATION_ID=$(curl -X POST \
-H "Authorization: token $TOKEN" \
"http://localhost:3000/api/v1/repos/owner/repo/mirror-sync" | jq -r '.operation_id')
# Subscribe to progress updates (SSE)
curl -N -H "Accept: text/event-stream" \
"http://localhost:3000/api/v2/operations/$OPERATION_ID/progress"
# Check operation status
curl "http://localhost:3000/api/v2/operations/$OPERATION_ID"
# Cancel operation
curl -X DELETE "http://localhost:3000/api/v2/operations/$OPERATION_ID"
```
**Checklist:**
- [ ] Operation ID returned from long-running endpoints
- [ ] SSE stream provides real-time updates
- [ ] Progress includes phase, percentage, ETA
- [ ] Completed operations can be queried
- [ ] Operations can be cancelled
### 4.2 Idempotency Middleware
```bash
# First request - should execute
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Idempotency-Key: unique-key-123" \
-H "Content-Type: application/json" \
-d '{"title": "Test Issue", "body": "Test body"}' \
http://localhost:3000/api/v1/repos/owner/repo/issues
# Duplicate request - should return cached response
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Idempotency-Key: unique-key-123" \
-H "Content-Type: application/json" \
-d '{"title": "Test Issue", "body": "Test body"}' \
http://localhost:3000/api/v1/repos/owner/repo/issues
# Should see header: Idempotency-Replayed: true
# Should NOT create duplicate issue
```
**Checklist:**
- [ ] First request executes normally
- [ ] Duplicate request returns cached response
- [ ] `Idempotency-Replayed: true` header on cached responses
- [ ] Different idempotency keys execute separately
- [ ] Keys expire after 24 hours
### 4.3 Webhook Retry
```bash
# Configure a webhook to a non-responsive endpoint
# Trigger an event (push, issue create, etc.)
# Check webhook delivery logs
curl -H "Authorization: token $TOKEN" \
"http://localhost:3000/api/v1/repos/owner/repo/hooks/1/deliveries"
```
**Checklist:**
- [ ] Failed deliveries are retried
- [ ] Exponential backoff between retries
- [ ] Max retries respected
- [ ] Delivery attempts logged
- [ ] Eventually marked as failed after max retries
### 4.4 Circuit Breaker
```bash
# This is internal - check via metrics or logs
# Simulate external service failure
# Verify circuit opens after threshold
# Verify circuit half-opens after timeout
# Verify circuit closes after success
```
**Checklist:**
- [ ] Circuit opens after consecutive failures
- [ ] Requests fail fast when circuit open
- [ ] Circuit transitions to half-open after timeout
- [ ] Successful request closes circuit
- [ ] Circuit state visible in health endpoint
---
## 5. Phase 4: SDK and CLI Tools
### 5.1 CLI Tool (gitea-cli)
```bash
# Build CLI
cd cmd/gitea-cli && go build -o gitea-cli .
# Login
./gitea-cli auth login --server http://localhost:3000 --token $TOKEN
# Check auth status
./gitea-cli auth status
# Upload release asset
./gitea-cli upload release-asset \
--owner myorg \
--repo myrepo \
--release-id 1 \
--file ./large-file.zip
# List pending uploads
./gitea-cli upload list
# Resume interrupted upload
./gitea-cli upload resume --session-id <session-id>
# Logout
./gitea-cli auth logout
```
**Checklist:**
- [ ] Login stores credentials securely
- [ ] Upload shows progress bar
- [ ] Chunked upload works for large files
- [ ] Resume works after interruption
- [ ] Checksum verification passes
### 5.2 Go SDK
```go
package main
import (
"fmt"
gitea "code.gitea.io/gitea/sdk/go"
)
func main() {
client := gitea.NewClient("http://localhost:3000", "your-token")
// Get user
user, err := client.GetCurrentUser()
if err != nil {
panic(err)
}
fmt.Printf("Logged in as: %s\n", user.UserName)
// Upload file with progress
err = client.UploadReleaseAsset(
"owner", "repo", 1,
"./large-file.zip",
gitea.WithProgress(func(current, total int64) {
fmt.Printf("\rProgress: %d/%d", current, total)
}),
)
}
```
**Checklist:**
- [ ] Client initializes with token
- [ ] Basic API calls work
- [ ] Chunked upload works
- [ ] Progress callback fires
- [ ] Errors properly typed
### 5.3 Python SDK
```python
from gitea_sdk import GiteaClient
client = GiteaClient("http://localhost:3000", token="your-token")
# Get user
user = client.get_current_user()
print(f"Logged in as: {user.username}")
# Upload with progress
def on_progress(current, total):
print(f"\rProgress: {current}/{total}", end="")
client.upload_release_asset(
owner="myorg",
repo="myrepo",
release_id=1,
file_path="./large-file.zip",
on_progress=on_progress
)
```
**Checklist:**
- [ ] pip install works
- [ ] Client connects with token
- [ ] Basic API calls work
- [ ] Type hints work in IDE
- [ ] Chunked upload works
### 5.4 TypeScript SDK
```typescript
import { GiteaClient } from '@gitea/sdk';
const client = new GiteaClient({
baseUrl: 'http://localhost:3000',
token: 'your-token'
});
// Get user
const user = await client.getCurrentUser();
console.log(`Logged in as: ${user.username}`);
// Upload with progress
await client.uploadReleaseAsset({
owner: 'myorg',
repo: 'myrepo',
releaseId: 1,
file: fs.createReadStream('./large-file.zip'),
onProgress: (current, total) => {
console.log(`Progress: ${current}/${total}`);
}
});
```
**Checklist:**
- [ ] npm install works
- [ ] TypeScript types correct
- [ ] Works in Node.js
- [ ] Works in browser (where applicable)
- [ ] Async/await works properly
### 5.5 C# SDK
```csharp
using Gitea.SDK;
var client = new GiteaClient("http://localhost:3000", "your-token");
// Get user
var user = await client.GetCurrentUserAsync();
Console.WriteLine($"Logged in as: {user.UserName}");
// Upload with progress
await client.UploadReleaseAssetAsync(
owner: "myorg",
repo: "myrepo",
releaseId: 1,
filePath: "./large-file.zip",
onProgress: (current, total) => {
Console.WriteLine($"Progress: {current}/{total}");
}
);
```
**Checklist:**
- [ ] NuGet package installs
- [ ] .NET 6+ compatible
- [ ] Async methods work
- [ ] Progress events fire
- [ ] Proper disposal (IDisposable)
### 5.6 Java SDK
```java
import io.gitea.sdk.GiteaClient;
GiteaClient client = new GiteaClient("http://localhost:3000", "your-token");
// Get user
User user = client.getCurrentUser();
System.out.println("Logged in as: " + user.getUserName());
// Upload with progress
client.uploadReleaseAsset(
"myorg", "myrepo", 1,
new File("./large-file.zip"),
(current, total) -> {
System.out.printf("Progress: %d/%d%n", current, total);
}
);
```
**Checklist:**
- [ ] Maven/Gradle dependency works
- [ ] Java 11+ compatible
- [ ] Fluent API works
- [ ] Progress callback fires
- [ ] Proper resource management
---
## 6. Phase 5: Organization Profiles
### 6.1 Pinned Repositories
```bash
# List pinned repos
curl -H "Authorization: token $TOKEN" \
"http://localhost:3000/api/v1/orgs/myorg/pinned"
# Pin a repository
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"repo_name": "my-repo"}' \
"http://localhost:3000/api/v1/orgs/myorg/pinned"
# Create a pinned group
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Core Projects"}' \
"http://localhost:3000/api/v1/orgs/myorg/pinned/groups"
# Add repo to group
curl -X PUT \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"group_id": 1}' \
"http://localhost:3000/api/v1/orgs/myorg/pinned/my-repo"
# Reorder pinned repos
curl -X PUT \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"order": ["repo1", "repo2", "repo3"]}' \
"http://localhost:3000/api/v1/orgs/myorg/pinned/reorder"
# Unpin repository
curl -X DELETE \
-H "Authorization: token $TOKEN" \
"http://localhost:3000/api/v1/orgs/myorg/pinned/my-repo"
```
**Web UI Checklist:**
- [ ] Pinned repos appear on org profile page
- [ ] Groups are collapsible
- [ ] Repo cards show stars, forks, language
- [ ] Reordering works via drag-and-drop (if implemented)
### 6.2 Public Members
```bash
# List public members with roles
curl "http://localhost:3000/api/v1/orgs/myorg/public_members/roles"
# Make yourself public
curl -X PUT \
-H "Authorization: token $TOKEN" \
"http://localhost:3000/api/v1/orgs/myorg/public_members/myusername"
# Remove public visibility
curl -X DELETE \
-H "Authorization: token $TOKEN" \
"http://localhost:3000/api/v1/orgs/myorg/public_members/myusername"
```
**Checklist:**
- [ ] Public members shown on org profile
- [ ] Roles displayed (Owner, Admin, Member)
- [ ] "and X more" overflow works
- [ ] Opt-in/opt-out works
---
## 7. Phase 5: Gitea Pages
### 7.1 Basic Pages Setup
```bash
# Create test repo with landing.yaml
mkdir test-pages && cd test-pages
git init
cat > .gitea/landing.yaml << 'EOF'
enabled: true
template: simple
branding:
primary_color: "#4a90d9"
hero:
title: "My Project"
tagline: "The best project ever"
EOF
cat > README.md << 'EOF'
# My Project
Welcome to my project!
## Features
- Feature 1
- Feature 2
EOF
git add -A && git commit -m "Initial commit"
git push origin main
```
### 7.2 Pages API
```bash
# Get pages config
curl -H "Authorization: token $TOKEN" \
"http://localhost:3000/api/v1/repos/owner/repo/pages"
# Enable pages
curl -X PUT \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled": true, "template": "simple"}' \
"http://localhost:3000/api/v1/repos/owner/repo/pages"
# Add custom domain
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"domain": "myproject.example.com"}' \
"http://localhost:3000/api/v1/repos/owner/repo/pages/domains"
# Verify domain
curl -X POST \
-H "Authorization: token $TOKEN" \
"http://localhost:3000/api/v1/repos/owner/repo/pages/domains/myproject.example.com/verify"
# Disable pages
curl -X DELETE \
-H "Authorization: token $TOKEN" \
"http://localhost:3000/api/v1/repos/owner/repo/pages"
```
### 7.3 Template Testing
Test each template by visiting `http://localhost:3000/owner/repo/pages`:
**Simple Template:**
- [ ] Hero section displays
- [ ] README content renders
- [ ] Repo stats shown in footer
**Documentation Template:**
- [ ] Sidebar navigation works
- [ ] `/docs` folder content loads
- [ ] Search works (if enabled)
- [ ] "Edit this page" links work
**Product Template:**
- [ ] Hero with background
- [ ] Features grid displays
- [ ] Screenshot section works
- [ ] Releases section shows latest
**Portfolio Template:**
- [ ] Gallery grid displays
- [ ] Lightbox works on click
- [ ] Captions display
---
## 8. Phase 5: Wiki V2 API
### 8.1 CRUD Operations
```bash
BASE="http://localhost:3000/api/v2/repos/owner/repo/wiki"
# List pages
curl -H "Authorization: token $TOKEN" "$BASE/pages"
# Get single page
curl -H "Authorization: token $TOKEN" "$BASE/pages/Home"
# Create page
curl -X POST \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Test-Page", "content": "# Test\n\nContent here."}' \
"$BASE/pages"
# Update page
curl -X PUT \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"content": "# Updated\n\nNew content."}' \
"$BASE/pages/Test-Page"
# Rename page
curl -X PUT \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d '{"rename_to": "New-Page-Name"}' \
"$BASE/pages/Test-Page"
# Delete page
curl -X DELETE \
-H "Authorization: token $TOKEN" \
"$BASE/pages/New-Page-Name"
```
### 8.2 Search, Graph, Stats
```bash
# Search
curl -H "Authorization: token $TOKEN" "$BASE/search?q=installation"
# Link graph
curl -H "Authorization: token $TOKEN" "$BASE/graph"
# Statistics
curl -H "Authorization: token $TOKEN" "$BASE/stats"
# Page revisions
curl -H "Authorization: token $TOKEN" "$BASE/pages/Home/revisions"
```
### 8.3 Response Validation
**Page Response Should Include:**
- [ ] `content` - raw markdown
- [ ] `content_html` - rendered HTML
- [ ] `links_out` - outgoing wiki links
- [ ] `links_in` - incoming links
- [ ] `word_count` - accurate count
- [ ] `last_commit` - author, date, message
**Stats Response Should Include:**
- [ ] `total_pages`
- [ ] `total_words`
- [ ] `health.orphaned_pages`
- [ ] `health.dead_links`
- [ ] `health.outdated_pages`
- [ ] `health.short_pages`
- [ ] `top_linked`
---
## 9. Regression Testing
### Critical Existing Features
These MUST still work:
```bash
# Repository clone
git clone http://localhost:3000/owner/repo.git
# Push
git push origin main
# V1 API still works
curl http://localhost:3000/api/v1/version
curl -H "Authorization: token $TOKEN" http://localhost:3000/api/v1/user
curl http://localhost:3000/api/v1/repos/owner/repo
# Wiki V1 still works
curl http://localhost:3000/api/v1/repos/owner/repo/wiki/pages
curl http://localhost:3000/api/v1/repos/owner/repo/wiki/page/Home
# Issues
curl http://localhost:3000/api/v1/repos/owner/repo/issues
# Pull requests
curl http://localhost:3000/api/v1/repos/owner/repo/pulls
```
**Checklist:**
- [ ] Git clone (HTTP)
- [ ] Git clone (SSH)
- [ ] Git push
- [ ] Branch creation
- [ ] Tag creation
- [ ] Pull request creation
- [ ] Pull request merge
- [ ] Issue creation
- [ ] Wiki (web UI)
- [ ] Wiki (V1 API)
- [ ] User login
- [ ] Organization operations
---
## 10. Complete Smoke Test Script
```bash
#!/bin/bash
set -e
BASE="${GITEA_URL:-http://localhost:3000}"
TOKEN="${GITEA_TOKEN:-your-token}"
OWNER="${TEST_OWNER:-testorg}"
REPO="${TEST_REPO:-testrepo}"
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
pass() { echo -e "${GREEN}${NC} $1"; }
fail() { echo -e "${RED}${NC} $1"; FAILED=1; }
test_endpoint() {
local name=$1
local method=${2:-GET}
local url=$3
local data=$4
if [ -n "$data" ]; then
response=$(curl -sf -X $method -H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" -d "$data" "$url" 2>/dev/null) && pass "$name" || fail "$name"
else
response=$(curl -sf -X $method -H "Authorization: token $TOKEN" "$url" 2>/dev/null) && pass "$name" || fail "$name"
fi
}
echo "=== Gitea v1.26.0 Comprehensive Smoke Tests ==="
echo ""
echo "--- Phase 1: API Reliability ---"
test_endpoint "Version endpoint" GET "$BASE/api/v1/version"
test_endpoint "Request ID header" GET "$BASE/api/v1/version"
echo ""
echo "--- Phase 2: V2 API ---"
test_endpoint "V2 Version" GET "$BASE/api/v2/version"
test_endpoint "V2 User" GET "$BASE/api/v2/user"
test_endpoint "V2 Docs" GET "$BASE/api/v2/docs"
test_endpoint "V2 Batch Files" POST "$BASE/api/v2/batch/files" '{"requests":[]}'
test_endpoint "V2 AI Repo Summary" POST "$BASE/api/v2/ai/repo/summary" "{\"owner\":\"$OWNER\",\"repo\":\"$REPO\"}"
echo ""
echo "--- Phase 3: Reliability ---"
test_endpoint "Health Check" GET "$BASE/api/v2/health"
echo ""
echo "--- Phase 5: Org Profiles ---"
test_endpoint "Org Pinned Repos" GET "$BASE/api/v1/orgs/$OWNER/pinned"
test_endpoint "Org Public Members" GET "$BASE/api/v1/orgs/$OWNER/public_members/roles"
echo ""
echo "--- Phase 5: Pages ---"
test_endpoint "Pages Config" GET "$BASE/api/v1/repos/$OWNER/$REPO/pages"
echo ""
echo "--- Phase 5: Wiki V2 ---"
test_endpoint "Wiki List Pages" GET "$BASE/api/v2/repos/$OWNER/$REPO/wiki/pages"
test_endpoint "Wiki Search" GET "$BASE/api/v2/repos/$OWNER/$REPO/wiki/search?q=test"
test_endpoint "Wiki Graph" GET "$BASE/api/v2/repos/$OWNER/$REPO/wiki/graph"
test_endpoint "Wiki Stats" GET "$BASE/api/v2/repos/$OWNER/$REPO/wiki/stats"
echo ""
echo "--- Regression: V1 API ---"
test_endpoint "V1 User" GET "$BASE/api/v1/user"
test_endpoint "V1 Repos" GET "$BASE/api/v1/repos/$OWNER/$REPO"
test_endpoint "V1 Wiki Pages" GET "$BASE/api/v1/repos/$OWNER/$REPO/wiki/pages"
echo ""
if [ -z "$FAILED" ]; then
echo -e "${GREEN}All tests passed!${NC}"
exit 0
else
echo -e "${RED}Some tests failed!${NC}"
exit 1
fi
```
Save as `smoke-test.sh` and run:
```bash
chmod +x smoke-test.sh
GITEA_URL=http://localhost:3000 GITEA_TOKEN=your-token ./smoke-test.sh
```
---
## 11. Rollback Plan
If any issues are found:
```bash
# 1. Stop current version
docker-compose down
# 2. Restore previous version
docker pull gitea/gitea:1.25.3
# 3. Update docker-compose.yml to use 1.25.3
# 4. Start previous version
docker-compose up -d
```
**Safe to rollback because:**
- New tables (wiki_index, pages_*, org_pinned_*) are ignored by old version
- No existing tables were modified
- V1 API unchanged
- No data migration required
---
## Summary
**Testing Priority:**
1. **Critical:** Idempotency, chunked uploads, V1 API regression
2. **High:** V2 batch/streaming, wiki V2 CRUD, pages rendering
3. **Medium:** SDKs, CLI, org profiles, operation progress
4. **Low:** Scalar docs, AI context endpoints
**Recommended Testing Time:**
- Automated tests: 30 minutes
- Manual testing: 2-4 hours
- Staging soak test: 24-48 hours
- Total: 2-3 days before production