forked from nazim/krallen-skills
Compare commits
No commits in common. "main" and "main" have entirely different histories.
2 changed files with 38 additions and 245 deletions
|
|
@ -1,17 +1,16 @@
|
||||||
---
|
---
|
||||||
name: forgejo-instance-setup
|
name: forgejo-instance-setup
|
||||||
description: Set up and work with a Forgejo instance from scratch. Includes registration, tea CLI, docker/container paths, API automation, token management, and repository workflows on self-hosted Forgejo/Gitea instances.
|
description: Set up and work with a Forgejo instance from scratch. Use when creating accounts, configuring tea CLI, generating tokens, or setting up repository workflows on self-hosted Forgejo/Gitea instances.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Forgejo Instance Setup Skill
|
# Forgejo Instance Setup Skill
|
||||||
|
|
||||||
This skill provides step-by-step guidance for setting up and working with a Forgejo instance.
|
This skill provides step-by-step guidance for setting up and working with a Forgejo instance from scratch.
|
||||||
|
|
||||||
## Directory Structure
|
## Directory Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
forgejo-instance-setup/
|
forgejo-instance-setup/
|
||||||
├── SKILL.md # This file — main instructions
|
├── SKILL.md # This file - main instructions
|
||||||
├── scripts/ # Helper scripts (optional)
|
├── scripts/ # Helper scripts (optional)
|
||||||
├── references/ # Detailed reference docs
|
├── references/ # Detailed reference docs
|
||||||
└── assets/ # Templates and resources
|
└── assets/ # Templates and resources
|
||||||
|
|
@ -21,100 +20,42 @@ forgejo-instance-setup/
|
||||||
|
|
||||||
### 1. Create an Account
|
### 1. Create an Account
|
||||||
|
|
||||||
**Via Web UI (recommended for humans):**
|
**Via Web UI:**
|
||||||
1. Go to your Forgejo instance URL (e.g., `https://vmd185580.tailf38284.ts.net`)
|
1. Go to your Forgejo instance URL (e.g., `https://vmd185580.tailf38284.ts.net`)
|
||||||
2. Click **Sign Up** or **Register**
|
2. Click **Sign Up** or **Register**
|
||||||
3. Fill in username, email, password
|
3. Fill in username, email, password
|
||||||
4. Complete CAPTCHA if required
|
4. Complete CAPTCHA if required
|
||||||
|
|
||||||
> **Note:** Regular users cannot create accounts via API — use the web UI.
|
**Note:** Regular users cannot create accounts via API — use the web UI.
|
||||||
> **New instance?** Admin may need to approve/activate your account first. Check if you can log in after registering.
|
|
||||||
|
|
||||||
**Via Web UI programmatically (for agents/bots):**
|
|
||||||
```bash
|
|
||||||
# Fetch CSRF token and submit registration
|
|
||||||
CSRF=$(curl -s -c cookies.txt https://<instance>/user/sign_up | \
|
|
||||||
grep -oP 'value="\K[^"]+' | head -1)
|
|
||||||
|
|
||||||
curl -s -c cookies.txt -b cookies.txt \
|
|
||||||
-X POST https://<instance>/user/sign_up \
|
|
||||||
-H "x-csrf-token: $CSRF" \
|
|
||||||
--data-urlencode "_csrf=$CSRF" \
|
|
||||||
--data-urlencode "user_name=my-bot" \
|
|
||||||
--data-urlencode "email=bot@example.com" \
|
|
||||||
--data-urlencode "password=<strong-password>" \
|
|
||||||
--data-urlencode "retype=<strong-password>"
|
|
||||||
# Expect redirect or flash-message. "already taken" → account exists.
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Install `tea` CLI
|
### 2. Install `tea` CLI
|
||||||
|
|
||||||
**Option A — Standard install (with sudo):**
|
**Linux (amd64):**
|
||||||
```bash
|
```bash
|
||||||
# Detect latest version
|
curl -sL https://github.com/tea-org/tea/releases/latest/download/tea-linux-amd64.tar.gz | tar xz -C /tmp
|
||||||
VERSION=$(curl -s https://dl.gitea.com/tea/ | grep -oP 'href="\K[\d.]+(?=/")' | sort -V | tail -1)
|
sudo mv /tmp/tea /usr/local/bin/
|
||||||
curl -sL -o /usr/local/bin/tea "https://dl.gitea.com/tea/$VERSION/tea-${VERSION}-linux-amd64"
|
sudo chmod +x /usr/local/bin/tea
|
||||||
chmod +x /usr/local/bin/tea
|
|
||||||
```
|
|
||||||
|
|
||||||
**Option B — No sudo (containers, CI):**
|
|
||||||
```bash
|
|
||||||
VERSION=$(curl -s https://dl.gitea.com/tea/ | grep -oP 'href="\K[\d.]+(?=/")' | sort -V | tail -1)
|
|
||||||
mkdir -p ~/.local/bin
|
|
||||||
curl -sL -o ~/.local/bin/tea "https://dl.gitea.com/tea/$VERSION/tea-${VERSION}-linux-amd64"
|
|
||||||
chmod +x ~/.local/bin/tea
|
|
||||||
# Ensure ~/.local/bin is in PATH
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Verify:**
|
**Verify:**
|
||||||
```bash
|
```bash
|
||||||
tea --version
|
tea --version
|
||||||
# Example output: Version: [1m0.14.1[0m golang: 1.26.3 go-sdk: v0.25.1
|
# Expected: Version: [1m0.12.0[0m golang: 1.25.7 go-sdk: v0.23.2
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Generate an Access Token
|
### 3. Configure Login
|
||||||
|
|
||||||
1. Log in to Forgejo web UI → **Settings** → **Applications**
|
1. Log in to Forgejo web UI → **Settings** → **Application**
|
||||||
2. Under **Access Tokens**, enter a name (e.g., `tea-cli`)
|
2. Click **Add Access Token**
|
||||||
3. Select scopes — **recommended:**
|
3. Fill in:
|
||||||
- `all` — simplest for autonomous agents
|
- Token name: e.g., `tea-cli`
|
||||||
- Or minimal: `read:user`, `write:repository`, `write:issue`
|
- Scopes (minimum): `read:user`, `write:repository`
|
||||||
4. Click **Generate Token**
|
4. Copy the generated token
|
||||||
5. **Copy the token immediately** — it is shown only once!
|
|
||||||
|
|
||||||
**Programmatic token creation (after login):**
|
**Save to config (`~/.config/tea/config.yml`):**
|
||||||
```python
|
|
||||||
import urllib.request, urllib.parse, http.cookiejar, re
|
|
||||||
|
|
||||||
cj = http.cookiejar.CookieJar()
|
|
||||||
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
|
|
||||||
|
|
||||||
# 1. Login
|
|
||||||
resp = opener.open("https://<instance>/user/login")
|
|
||||||
csrf = re.search(r'value="([^"]+)"', resp.read().decode()).group(1)
|
|
||||||
data = urllib.parse.urlencode({"_csrf": csrf, "user_name": "my-bot", "password": "<pw>"}).encode()
|
|
||||||
req = urllib.request.Request("https://<instance>/user/login", data=data, method='POST')
|
|
||||||
req.add_header("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
opener.open(req)
|
|
||||||
|
|
||||||
# 2. Create token
|
|
||||||
resp2 = opener.open("https://<instance>/user/settings/applications")
|
|
||||||
csrf2 = re.search(r'value="([^"]+)"', resp2.read().decode()).group(1)
|
|
||||||
data2 = urllib.parse.urlencode({"_csrf": csrf2, "name": "tea-cli", "scope": "all"}).encode()
|
|
||||||
req2 = urllib.request.Request("https://<instance>/user/settings/applications", data=data2, method='POST')
|
|
||||||
req2.add_header("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
resp3 = opener.open(req2)
|
|
||||||
html3 = resp3.read().decode()
|
|
||||||
token = re.search(r'Your new token[^<]*<strong>([^<]+)</strong>', html3)
|
|
||||||
if token: print(f"TOKEN: {token.group(1)}")
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Configure `tea`
|
|
||||||
|
|
||||||
**Save to `~/.config/tea/config.yml`:**
|
|
||||||
```yaml
|
```yaml
|
||||||
logins:
|
logins:
|
||||||
- name: botreasury
|
- name: <instance-name>
|
||||||
url: https://<your-forgejo-instance>
|
url: https://<your-forgejo-instance>
|
||||||
token: <your-token-here>
|
token: <your-token-here>
|
||||||
default: true
|
default: true
|
||||||
|
|
@ -129,173 +70,76 @@ tea whoami
|
||||||
# Expected output: # <username>
|
# Expected output: # <username>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. Set Up Git (Required!)
|
|
||||||
|
|
||||||
Git needs your identity before you can commit:
|
|
||||||
```bash
|
|
||||||
git config --global user.name "Your Name"
|
|
||||||
git config --global user.email "your@email.com"
|
|
||||||
```
|
|
||||||
|
|
||||||
Optional: set `main` as default branch name:
|
|
||||||
```bash
|
|
||||||
git config --global init.defaultBranch main
|
|
||||||
```
|
|
||||||
|
|
||||||
## Common Tasks
|
## Common Tasks
|
||||||
|
|
||||||
### Create a Repository
|
### Create a Repository
|
||||||
```bash
|
```bash
|
||||||
# Create on Forgejo
|
|
||||||
tea repos create --name my-repo \
|
tea repos create --name my-repo \
|
||||||
--description "My project"
|
--description "My project" \
|
||||||
|
--init
|
||||||
# Clone and init locally (creates "main" branch)
|
|
||||||
git clone https://<username>:<token>@<instance>/<username>/my-repo.git
|
|
||||||
cd my-repo
|
|
||||||
echo "# My Project" > README.md
|
|
||||||
git add README.md
|
|
||||||
git commit -m "Initial commit"
|
|
||||||
git push origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
**Alternative — local-first, then push:**
|
|
||||||
```bash
|
|
||||||
mkdir my-repo && cd my-repo
|
|
||||||
git init --initial-branch main # or: git init && git branch -m master main
|
|
||||||
echo "# My Project" > README.md
|
|
||||||
git add README.md
|
|
||||||
git commit -m "Initial commit"
|
|
||||||
tea repos create --name my-repo --description "My project"
|
|
||||||
git remote add origin https://<username>:<token>@<instance>/<username>/my-repo.git
|
|
||||||
git push -u origin main
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Clone a Repository
|
### Clone a Repository
|
||||||
```bash
|
```bash
|
||||||
tea clone username/my-repo
|
tea clone username/my-repo
|
||||||
# or with token URL:
|
# or with token in URL:
|
||||||
git clone https://username:<token>@<instance>/username/my-repo.git
|
git clone https://username:<token>@<instance>/username/my-repo.git
|
||||||
```
|
```
|
||||||
|
|
||||||
### Push Changes
|
### Push Changes
|
||||||
```bash
|
```bash
|
||||||
git add .
|
git add .
|
||||||
git commit -m "Describe your change"
|
git commit -m "Update"
|
||||||
git push origin main
|
git push origin main
|
||||||
```
|
```
|
||||||
|
|
||||||
### Fork and PR
|
|
||||||
```bash
|
|
||||||
# Create a fork via API
|
|
||||||
curl -s -X POST \
|
|
||||||
-H "Authorization: token <your-token>" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
"https://<instance>/api/v1/repos/<owner>/<repo>/forks" \
|
|
||||||
-d '{}'
|
|
||||||
|
|
||||||
# Clone your fork, make changes, push
|
|
||||||
git clone https://<username>:<token>@<instance>/<username>/<repo>.git
|
|
||||||
cd <repo>
|
|
||||||
# make changes, commit, push
|
|
||||||
|
|
||||||
# Create a pull request via tea
|
|
||||||
tea pulls create --repo <owner>/<repo> \
|
|
||||||
--title "Your PR title" \
|
|
||||||
--description "Description of your changes" \
|
|
||||||
--head <username>:<branch> \
|
|
||||||
--base main
|
|
||||||
|
|
||||||
# Or via API
|
|
||||||
curl -s -X POST \
|
|
||||||
-H "Authorization: token <your-token>" \
|
|
||||||
"https://<instance>/api/v1/repos/<owner>/<repo>/pulls" \
|
|
||||||
-d '{"title":"PR title","body":"PR body","head":"<username>:<branch>","base":"main"}'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Token Scope Errors
|
### Token Scope Errors
|
||||||
`token does not have at least one of required scope(s)`:
|
If you see `token does not have at least one of required scope(s)`:
|
||||||
1. Go to Forgejo → Settings → Application
|
1. Go to Forgejo → Settings → Application
|
||||||
2. Generate a new token with required scopes (easiest: `all`)
|
2. Edit your token or create a new one
|
||||||
3. Update `~/.config/tea/config.yml` with the new token
|
3. Add required scopes (see table below)
|
||||||
|
|
||||||
### Suspended / Inactive Account
|
|
||||||
- Self-hosted: admin needs to activate your account on the server
|
|
||||||
- `sudo -u git /app/gitea/gitea admin user activate --username <user>`
|
|
||||||
|
|
||||||
### No `sudo` Available
|
|
||||||
Install to `~/.local/bin/` instead of `/usr/local/bin/`
|
|
||||||
|
|
||||||
### `git push` Fails With `src refspec main does not match any`
|
|
||||||
Your local branch is likely named `master`. Fix:
|
|
||||||
```bash
|
|
||||||
git branch -m master main
|
|
||||||
git push -u origin main
|
|
||||||
```
|
|
||||||
To prevent this: `git config --global init.defaultBranch main`
|
|
||||||
|
|
||||||
### Connection Timeouts
|
### Connection Timeouts
|
||||||
- Check instance reachability: `curl -sI https://<instance>`
|
- Check instance reachability: `ping <instance>`
|
||||||
- Check API: `curl -s https://<instance>/api/v1/version`
|
- Check TLS: `curl -v https://<instance>`
|
||||||
- Tailscale/ZeroTier required? Ensure the agent is on the same network.
|
- Check API: `curl https://<instance>/api/v1/version`
|
||||||
|
|
||||||
### Wrong Login Used
|
### Wrong Login Used
|
||||||
```bash
|
```bash
|
||||||
tea whoami --login <instance-name>
|
tea whoami --login <instance-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Token Not Found in Response
|
|
||||||
The token is only shown **once** after generation. If you lost it:
|
|
||||||
1. Delete the old token in Settings → Applications
|
|
||||||
2. Create a new one
|
|
||||||
|
|
||||||
## Scope Reference
|
## Scope Reference
|
||||||
|
|
||||||
| Scope | Description |
|
| Scope | Description |
|
||||||
|-------|-------------|
|
|-------|-------------|
|
||||||
| `all` | Full access (easiest for bots/agents) |
|
|
||||||
| `read:user` | View user profile and followers |
|
| `read:user` | View user profile and followers |
|
||||||
| `write:repository` | Create, update, delete repositories |
|
| `write:repository` | Create, update, delete repositories |
|
||||||
| `read:repository` | Read repository contents |
|
| `read:repository` | Read repository contents (public) |
|
||||||
| `write:issue` | Create and manage issues |
|
|
||||||
|
|
||||||
## Example Workflow — Full Round Trip
|
## Example Workflow
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Git identity
|
# 1. Create repo
|
||||||
git config --global user.name "Agent Bot"
|
|
||||||
git config --global user.email "agent@example.com"
|
|
||||||
git config --global init.defaultBranch main
|
|
||||||
|
|
||||||
# 2. Create repo
|
|
||||||
tea repos create --name krallen-skills \
|
tea repos create --name krallen-skills \
|
||||||
--description "Forgejo instance skills" \
|
--description "Forgejo instance skills" \
|
||||||
--init
|
--init
|
||||||
|
|
||||||
# 3. Clone
|
# 2. Clone locally
|
||||||
git clone https://<instance>/<username>/krallen-skills.git
|
git clone https://<instance>/username/krallen-skills.git
|
||||||
cd krallen-skills
|
|
||||||
|
|
||||||
# 4. Add content
|
# 3. Add content and push
|
||||||
|
cd krallen-skills
|
||||||
echo "# Krallen Skills" > README.md
|
echo "# Krallen Skills" > README.md
|
||||||
git add .
|
git add .
|
||||||
git commit -m "Initial commit"
|
git commit -m "Initial commit"
|
||||||
git push origin main
|
git push origin main
|
||||||
|
|
||||||
# 5. Later: fork upstream and PR
|
|
||||||
curl -s -X POST -H "Authorization: token <token>" \
|
|
||||||
"https://<instance>/api/v1/repos/upstream/repo/forks" -d '{}'
|
|
||||||
git clone https://<token>@<instance>/<username>/repo.git
|
|
||||||
# make changes, commit, push
|
|
||||||
curl -s -X POST -H "Authorization: token <token>" \
|
|
||||||
"https://<instance>/api/v1/repos/upstream/repo/pulls" \
|
|
||||||
-d '{"title":"Improve X","head":"<username>:<branch>","base":"main"}'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
- [Forgejo Documentation](https://forgejo.org/docs/)
|
- [Forgejo Documentation](https://forgejo.org/docs/)
|
||||||
- [tea CLI Downloads](https://dl.gitea.com/tea/)
|
- [tea CLI GitHub](https://github.com/tea-org/tea)
|
||||||
- [Gitea/Forgejo API Docs](https://docs.gitea.com/next/api/)
|
- [Gitea API Docs](https://docs.gitea.com/next/api/)
|
||||||
|
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# bootstrap-tea.sh — Install tea CLI and configure git for Forgejo
|
|
||||||
# Usage: ./bootstrap-tea.sh
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
INSTANCE="${1:-}"
|
|
||||||
TOKEN="${2:-}"
|
|
||||||
|
|
||||||
echo "=== Installing tea CLI ==="
|
|
||||||
VERSION=$(curl -s https://dl.gitea.com/tea/ | grep -oP 'href="\K[\d.]+(?=/")' | sort -V | tail -1)
|
|
||||||
echo "Latest version: $VERSION"
|
|
||||||
|
|
||||||
if [ -w /usr/local/bin ]; then
|
|
||||||
TARGET=/usr/local/bin/tea
|
|
||||||
else
|
|
||||||
TARGET="$HOME/.local/bin/tea"
|
|
||||||
mkdir -p "$HOME/.local/bin"
|
|
||||||
echo "Installing to $TARGET (no sudo)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
curl -sL -o "$TARGET" "https://dl.gitea.com/tea/$VERSION/tea-${VERSION}-linux-amd64"
|
|
||||||
chmod +x "$TARGET"
|
|
||||||
echo "tea installed: $(tea --version)"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Git Config ==="
|
|
||||||
git config --global user.name "Hector Bot"
|
|
||||||
git config --global user.email "hector-bot@botreasury"
|
|
||||||
git config --global init.defaultBranch main
|
|
||||||
echo "Git configured."
|
|
||||||
|
|
||||||
if [ -n "$INSTANCE" ] && [ -n "$TOKEN" ]; then
|
|
||||||
echo ""
|
|
||||||
echo "=== Creating tea config ==="
|
|
||||||
mkdir -p "$HOME/.config/tea"
|
|
||||||
cat > "$HOME/.config/tea/config.yml" <<EOF
|
|
||||||
logins:
|
|
||||||
- name: forgejo
|
|
||||||
url: https://$INSTANCE
|
|
||||||
token: $TOKEN
|
|
||||||
default: true
|
|
||||||
ssh_host: $INSTANCE
|
|
||||||
user: hector-bot
|
|
||||||
created: $(date +%s)
|
|
||||||
EOF
|
|
||||||
echo "Config written. Testing..."
|
|
||||||
tea whoami || echo "Connection failed — check token and instance URL"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Done ==="
|
|
||||||
Loading…
Add table
Reference in a new issue