2026-02-28 12:08:13 -08:00
#!/usr/bin/env bash
set -eo pipefail
SCRIPT_DIR = " $( dirname " $0 " ) "
COMPOSE_FILE = " $SCRIPT_DIR /docker-compose.yml "
BASE_URL = " ${ 1 :- http : //localhost : 13001 } "
SERVICE_NAME = " ${ 2 :- forgejo -1 } "
ADMIN_USER = "testadmin"
ADMIN_PASS = "admin1234"
ADMIN_AUTH = " $ADMIN_USER : $ADMIN_PASS "
TESTBOT_AUTH = "testbot:testbot1234"
# --- Phase 1: Create users (sequential — prerequisite for everything) ---
echo "Creating admin user..."
docker compose -f " $COMPOSE_FILE " exec -T -u git " $SERVICE_NAME " \
forgejo admin user create --admin \
--username " $ADMIN_USER " \
--password " $ADMIN_PASS " \
--email testadmin@test.local \
--must-change-password= false
echo "Creating testbot user..."
docker compose -f " $COMPOSE_FILE " exec -T -u git " $SERVICE_NAME " \
forgejo admin user create \
--username testbot \
--password testbot1234 \
--email testbot@test.local \
--must-change-password= false
echo "Creating readonlyuser..."
docker compose -f " $COMPOSE_FILE " exec -T -u git " $SERVICE_NAME " \
forgejo admin user create \
--username readonlyuser \
--password readonly1234 \
--email readonlyuser@test.local \
--must-change-password= false
2026-03-09 10:46:10 -07:00
# --- Phase 2: Create repositories (parallel) ---
2026-02-28 12:08:13 -08:00
echo "Creating repositories..."
curl -sf -X POST " $BASE_URL /api/v1/user/repos " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"name": "test-repo", "private": false, "auto_init": true}' &
curl -sf -X POST " $BASE_URL /api/v1/user/repos " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"name": "test-repo-2", "description": "A second test repository", "private": false, "auto_init": true}' &
2026-03-09 10:46:10 -07:00
curl -sf -X POST " $BASE_URL /api/v1/user/repos " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"name": "archived-repo", "description": "An archived repository", "private": false, "auto_init": true}' &
2026-03-09 12:15:24 -07:00
curl -sf -X POST " $BASE_URL /api/v1/user/repos " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"name": "html-readme-repo", "description": "Repo with HTML in README", "private": false, "auto_init": true}' &
2026-02-28 12:08:13 -08:00
wait
echo "Repositories created."
2026-03-11 11:42:25 -07:00
# Archive the archived-repo (retry — the repo may not be ready immediately after creation)
2026-03-09 10:46:10 -07:00
echo "Archiving archived-repo..."
2026-03-11 11:42:25 -07:00
for attempt in 1 2 3; do
if curl -sf -X PATCH " $BASE_URL /api/v1/repos/ $ADMIN_USER /archived-repo " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"archived": true}' ; then
break
fi
echo " Archive attempt $attempt failed, retrying... "
sleep 1
done
2026-03-09 10:46:10 -07:00
2026-03-09 12:15:24 -07:00
# Update html-readme-repo README with HTML content
echo "Updating html-readme-repo README..."
2026-03-11 11:42:25 -07:00
for attempt in 1 2 3; do
README_SHA = $( curl -sf " $BASE_URL /api/v1/repos/ $ADMIN_USER /html-readme-repo/contents/README.md " \
-u " $ADMIN_AUTH " | python3 -c "import sys,json; print(json.load(sys.stdin)['sha'])" 2>/dev/null) && break
echo " README fetch attempt $attempt failed, retrying... "
sleep 1
done
2026-03-09 12:15:24 -07:00
README_PAYLOAD = $( python3 -c "
import base64, json
content = '' ' # HTML Readme Test
Regular markdown paragraph.
<details>
<summary>Click to expand</summary>
This content is hidden by default.
- Item A
- Item B
</details>
## Table
<table>
<tr><th>Name</th><th>Value</th></tr>
<tr><td>Alpha</td><td>1</td></tr>
<tr><td>Beta</td><td>2</td></tr>
</table>
## Keyboard Shortcuts
Press <kbd>Ctrl</kbd>+<kbd>C</kbd> to copy.
## Image
<img src = \" https://via.placeholder.com/150\" alt = \" placeholder\" width = \" 150\" >
## Security Test
<script>alert( "xss" ) </script>
<img src = \" x\" onerror = \" alert( 'xss' ) \" >
<iframe src = \" https://evil.example.com\" ></iframe>
<div onclick = \" alert( 'xss' ) \" >Click me</div>
'' '
b64 = base64.b64encode( content.encode( ) ) .decode( )
print( json.dumps( { 'content' : b64, 'message' : 'Add HTML to README' , 'sha' : '$README_SHA' } ) )
" )
curl -sf -X PUT " $BASE_URL /api/v1/repos/ $ADMIN_USER /html-readme-repo/contents/README.md " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d " $README_PAYLOAD "
2026-02-28 12:08:13 -08:00
# --- Phase 3: Create issues + code files + pagination issues (parallel) ---
# Create 25 pagination issues sequentially in a background subshell
# (sequential for deterministic issue numbering, background to overlap with other work)
echo "Creating pagination test issues..."
( for i in $( seq 1 25) ; do
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo-2/issues " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d " {\"title\": \"Pagination test issue $i \"} "
done ) &
# Create issues 1-3 as testbot (generates notifications for testadmin)
echo "Creating issues as testbot..."
for i in 1 2 3; do
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/issues " \
-u " $TESTBOT_AUTH " \
-H "Content-Type: application/json" \
-d " {\"title\": \"Test issue $i from integration tests\"} "
done
# Phase 3b: Independent operations on test-repo (parallel)
echo "Setting up test-repo content..."
# Comment on issue #1
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/issues/1/comments " \
-u " $TESTBOT_AUTH " \
-H "Content-Type: application/json" \
-d '{"body": "This is a test comment from testbot"}' &
# Add body text + close issue #3 in one PATCH
curl -sf -X PATCH " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/issues/3 " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"body": "This is the **markdown** body for issue 3.\n\nIt has multiple paragraphs.", "state": "closed"}' &
# Body for issue #1
curl -sf -X PATCH " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/issues/1 " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"body": "This is the **markdown** body for issue 1.\n\nIt has multiple paragraphs."}' &
# Body for issue #2
curl -sf -X PATCH " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/issues/2 " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"body": "This is the **markdown** body for issue 2.\n\nIt has multiple paragraphs."}' &
# Code files (sequential — both commit to same branch)
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/contents/hello.py " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d " {\"content\": \" $( echo -n 'print(\"Hello from Forgejo!\")' | base64) \", \"message\": \"Add hello.py\"} "
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/contents/src/main.py " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d " {\"content\": \" $( echo -n 'def main():\n print(\"Main module\")' | base64) \", \"message\": \"Add src/main.py\"} "
# Add testbot as collaborator
curl -sf -X PUT " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/collaborators/testbot " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"permission": "write"}' &
# Add readonlyuser as read-only collaborator
curl -sf -X PUT " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/collaborators/readonlyuser " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"permission": "read"}' &
# Create label
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/labels " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"name": "bug", "color": "#ee0701"}' &
# Create milestone
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/milestones " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"title": "v1.0", "description": "First release milestone", "due_on": "2026-03-01T00:00:00Z"}' &
wait
echo "Phase 3 done."
# --- Phase 3c: Metadata that depends on label/milestone existing ---
# Label ID 1 and milestone ID 1 are deterministic because they're the first
# created on a fresh Forgejo instance (auto-increment starts at 1).
echo "Setting issue metadata..."
# Add label to issue #1 (label ID 1 = "bug", created in Phase 3b)
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/issues/1/labels " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"labels": [1]}' &
# Set milestone + assignee on issue #1 (milestone ID 1 = "v1.0", created in Phase 3b)
curl -sf -X PATCH " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/issues/1 " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"milestone": 1, "assignees": ["testadmin"]}' &
wait
# --- Phase 4: Create branches + PRs (sequential — numbers must be deterministic #4, #5) ---
echo "Creating feature branch..."
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/contents/feature.txt " \
-u " $TESTBOT_AUTH " \
-H "Content-Type: application/json" \
-d " {\"content\": \" $( echo -n 'This file was added in a feature branch' | base64) \", \"message\": \"Add feature.txt\", \"new_branch\": \"feature-branch\"} "
echo "Creating pull request #4..."
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/pulls " \
-u " $TESTBOT_AUTH " \
-H "Content-Type: application/json" \
-d '{"title": "Add feature file", "head": "feature-branch", "base": "main", "body": "This PR adds a new feature file."}'
echo "Creating merge branch..."
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/contents/merge-test.txt " \
-u " $TESTBOT_AUTH " \
-H "Content-Type: application/json" \
-d " {\"content\": \" $( echo -n 'This file is for merge testing' | base64) \", \"message\": \"Add merge-test.txt\", \"new_branch\": \"merge-branch\"} "
echo "Creating pull request #5..."
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/pulls " \
-u " $TESTBOT_AUTH " \
-H "Content-Type: application/json" \
-d '{"title": "Merge test PR", "head": "merge-branch", "base": "main", "body": "This PR is for testing the merge flow."}'
# --- Phase 5: Post-PR metadata (parallel) ---
echo "Setting PR metadata..."
# Comment on PR #4
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/issues/4/comments " \
-u " $TESTBOT_AUTH " \
-H "Content-Type: application/json" \
-d '{"body": "Please review this PR when you get a chance."}' &
# Review on PR #4
curl -sf -X POST " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/pulls/4/reviews " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"event": "COMMENT", "body": "Looks good so far, just a few comments.", "comments": [{"path": "feature.txt", "body": "Consider a more descriptive filename.", "new_position": 1}]}' &
# Milestone + assignee on PR #4
curl -sf -X PATCH " $BASE_URL /api/v1/repos/ $ADMIN_USER /test-repo/issues/4 " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"milestone": 1, "assignees": ["testadmin"]}' &
wait
2026-03-08 10:25:39 -07:00
# --- Phase 6: Create API token for token-based auth tests ---
echo "Creating API token for testadmin..."
TOKEN_RESPONSE = $( curl -sf -X POST " $BASE_URL /api/v1/users/ $ADMIN_USER /tokens " \
-u " $ADMIN_AUTH " \
-H "Content-Type: application/json" \
-d '{"name": "integration-test-token", "scopes": ["read:user", "write:user", "read:repository", "write:repository", "read:issue", "write:issue", "read:notification", "write:notification", "read:organization"]}' )
API_TOKEN = $( echo " $TOKEN_RESPONSE " | python3 -c "import sys,json; print(json.load(sys.stdin)['sha1'])" )
echo " $API_TOKEN " > /tmp/forgejo_test_token.txt
echo "API token written to /tmp/forgejo_test_token.txt"
2026-02-28 12:08:13 -08:00
echo ""
echo "Seed data created successfully."