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
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>
25 KiB
25 KiB
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
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
# 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
# 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
# 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
# Trigger a 404 error
curl -s http://localhost:3000/api/v1/repos/nonexistent/nonexistent | jq .
Expected Response:
{
"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_idincluded in errors
3. Phase 2: V2 API with AI Features
3.1 V2 API Framework
# 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
# 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
# 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
# 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
# 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)
# 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
# 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: trueheader on cached responses- Different idempotency keys execute separately
- Keys expire after 24 hours
4.3 Webhook Retry
# 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
# 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)
# 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
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
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
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
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
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
# 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
# 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
# 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
# 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
/docsfolder 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
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
# 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 markdowncontent_html- rendered HTMLlinks_out- outgoing wiki linkslinks_in- incoming linksword_count- accurate countlast_commit- author, date, message
Stats Response Should Include:
total_pagestotal_wordshealth.orphaned_pageshealth.dead_linkshealth.outdated_pageshealth.short_pagestop_linked
9. Regression Testing
Critical Existing Features
These MUST still work:
# 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
#!/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:
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:
# 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:
- Critical: Idempotency, chunked uploads, V1 API regression
- High: V2 batch/streaming, wiki V2 CRUD, pages rendering
- Medium: SDKs, CLI, org profiles, operation progress
- 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