get gitea ready
Client tests / test (push) In progress
Server tests / browser (push) In progress
Server tests / unit (push) Failing after 12m50s

This commit is contained in:
KingKDot
2026-08-24 10:06:19 -05:00
parent 0921e39333
commit 2f0dc6a893
13 changed files with 337 additions and 19 deletions
+2 -1
View File
@@ -39,7 +39,8 @@ Thumbs.db
.gitignore
.gitattributes
# GitLab CI metadata is not needed in container build contexts
# CI metadata is not needed in container build contexts
.gitea/
.gitlab/
.gitlab-ci.yml
+48
View File
@@ -0,0 +1,48 @@
name: Client tests
on:
push:
paths:
- "Overlord-Client/**"
- "protocol/**"
- "scripts/generate-wire-protocol.ts"
- "go.work"
- "go.work.sum"
- ".gitea/workflows/client-tests.yml"
pull_request:
paths:
- "Overlord-Client/**"
- "protocol/**"
- "scripts/generate-wire-protocol.ts"
- "go.work"
- "go.work.sum"
- ".gitea/workflows/client-tests.yml"
workflow_dispatch:
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: Overlord-Client
steps:
- name: Checkout repository
uses: https://github.com/actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Go
uses: https://github.com/actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version-file: Overlord-Client/go.mod
cache: true
cache-dependency-path: |
Overlord-Client/go.sum
go.work.sum
- name: Download modules
run: go mod download
- name: Run tests
run: go test ./...
+71
View File
@@ -0,0 +1,71 @@
name: Server tests
on:
push:
paths:
- "Overlord-Server/**"
- "Overlord-Client/cmd/agent/wire/wire_contract_generated.go"
- "protocol/**"
- "scripts/generate-wire-protocol.ts"
- ".gitea/workflows/server-tests.yml"
pull_request:
paths:
- "Overlord-Server/**"
- "Overlord-Client/cmd/agent/wire/wire_contract_generated.go"
- "protocol/**"
- "scripts/generate-wire-protocol.ts"
- ".gitea/workflows/server-tests.yml"
workflow_dispatch:
permissions:
contents: read
jobs:
unit:
runs-on: ubuntu-latest
defaults:
run:
working-directory: Overlord-Server
steps:
- name: Checkout repository
uses: https://github.com/actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Bun
uses: https://github.com/oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.3.14
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Typecheck
run: bun run typecheck
- name: Verify generated wire protocol
run: bun run protocol:check
- name: Run unit tests
run: bun run test
browser:
runs-on: ubuntu-latest
defaults:
run:
working-directory: Overlord-Server
steps:
- name: Checkout repository
uses: https://github.com/actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Set up Bun
uses: https://github.com/oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.3.14
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Install Chromium and system dependencies
run: bunx playwright install --with-deps chromium
- name: Run browser tests
run: bun run test:e2e
+3
View File
@@ -32,6 +32,9 @@ config.json
.env
.docker-cache/
# Local Gitea Actions runner deployment
/deploy/gitea-runner/
# Go
bin/
*.exe
+1 -1
View File
@@ -137,7 +137,7 @@ RUN test "$(wc -l < ./public/index.html)" -lt 20 \
# Stage 2: runtime (slim)
# ============================================================
FROM oven/bun:1-slim AS runtime
LABEL org.opencontainers.image.source="https://gitlab.com/vxaboveground/overlord"
LABEL org.opencontainers.image.source="https://overlord.kyun.li/vxaboveground/overlord"
WORKDIR /app
# openssl/ca-certificates: TLS cert generation + HTTPS validation.
+1 -1
View File
@@ -15,7 +15,7 @@ show a connection error and nothing will work. That is expected.
The server is a separate component that you must deploy yourself.
2. Full setup instructions are in the README:
https://gitlab.com/vxaboveground/overlord/-/blob/main/README.md
https://overlord.kyun.li/vxaboveground/overlord/src/branch/main/README.md
3. Once the server is running, open this desktop client and enter the
server's IP address (or hostname) and port on the connection screen.
+1 -1
View File
@@ -49,7 +49,7 @@ bun run build:linux # Linux AppImage
Or from the repo root: `./scripts/build-desktop.sh` (or `scripts\build-desktop.bat` on Windows) picks the right target for the current OS.
Output lands in `src-tauri/target/release/bundle/`. The CI workflow in `.gitlab/ci/desktop-release.yml` builds the Windows NSIS installer on every push to `main` that changes the desktop application or its build inputs, and publishes it as a GitLab Release tagged `Overlord-Desktop-v<version>`.
Output lands in `src-tauri/target/release/bundle/`. The GitLab mirror's CI workflow in `.gitlab/ci/desktop-release.yml` builds the Windows NSIS installer on every mirrored push to `main` that changes the desktop application or its build inputs, and publishes it as a GitLab Release tagged `Overlord-Desktop-v<version>`.
## Configuration
+5 -5
View File
@@ -1,5 +1,5 @@
const TELEGRAM_URL = "https://t.me/Onimai";
const GITLAB_ISSUES_URL = "https://gitlab.com/vxaboveground/overlord/-/issues/new";
const GITEA_ISSUES_URL = "https://overlord.kyun.li/vxaboveground/overlord/issues/new";
let mounted = false;
@@ -90,11 +90,11 @@ export function showOnboardingIfNeeded(user) {
stepContent.innerHTML = `
<div class="account-onboarding__card">
<h2><i class="fa-brands fa-gitlab" aria-hidden="true"></i> Found a bug? Use GitLab Issues</h2>
<p><strong>This is the official place to report bugs.</strong> Create a GitLab issue with what happened, what you expected, and any useful screenshots or logs so the problem can be tracked and fixed.</p>
<h2><i class="fa-solid fa-code-branch" aria-hidden="true"></i> Found a bug? Use Gitea Issues</h2>
<p><strong>This is the official place to report bugs.</strong> Create a Gitea issue with what happened, what you expected, and any useful screenshots or logs so the problem can be tracked and fixed.</p>
<div class="account-onboarding__url-label">Full bug report link</div>
<a class="account-onboarding__url" href="${GITLAB_ISSUES_URL}" target="_blank" rel="noopener noreferrer">${GITLAB_ISSUES_URL}</a>
<a class="account-onboarding__open" href="${GITLAB_ISSUES_URL}" target="_blank" rel="noopener noreferrer"><i class="fa-brands fa-gitlab" aria-hidden="true"></i> Create a GitLab issue</a>
<a class="account-onboarding__url" href="${GITEA_ISSUES_URL}" target="_blank" rel="noopener noreferrer">${GITEA_ISSUES_URL}</a>
<a class="account-onboarding__open" href="${GITEA_ISSUES_URL}" target="_blank" rel="noopener noreferrer"><i class="fa-solid fa-code-branch" aria-hidden="true"></i> Create a Gitea issue</a>
</div>
`;
progressText.textContent = "Step 2 of 2";
@@ -22,6 +22,7 @@ type AgentCommand = {
class TransferTestAgent {
private socket: WebSocket | null = null;
private downloads = new Map<string, Uint8Array>();
clientId = CLIENT_ID;
setDownload(path: string, bytes: Uint8Array): void {
this.downloads.set(path, bytes);
@@ -76,6 +77,12 @@ class TransferTestAgent {
return;
}
if (message.type === "hello_ack") {
if (typeof message.id !== "string" || !message.id) {
clearTimeout(timeout);
reject(new Error("Agent hello acknowledgement did not include a client ID"));
return;
}
this.clientId = message.id;
clearTimeout(timeout);
resolve();
return;
@@ -163,7 +170,7 @@ test.describe("file transfer HTTP API runtime", () => {
const requestUpload = await api.post("/api/file/upload/request", {
data: {
clientId: CLIENT_ID,
clientId: agent.clientId,
path: remotePath,
fileName: "overlord-e2e-upload.bin",
},
@@ -185,7 +192,7 @@ test.describe("file transfer HTTP API runtime", () => {
const pullHeaders = {
"x-agent-token": AGENT_TOKEN,
"x-overlord-client-id": CLIENT_ID,
"x-overlord-client-id": agent.clientId,
};
const pull = await api.get(staged.pullUrl, { headers: pullHeaders });
expect(pull.ok()).toBeTruthy();
@@ -204,7 +211,7 @@ test.describe("file transfer HTTP API runtime", () => {
agent.setDownload(remotePath, downloadBytes);
const requestDownload = await api.post("/api/file/download/request", {
data: { clientId: CLIENT_ID, path: remotePath },
data: { clientId: agent.clientId, path: remotePath },
});
expect(requestDownload.ok()).toBeTruthy();
const { downloadUrl } = await requestDownload.json();
+2
View File
@@ -113,6 +113,8 @@ export default async function globalSetup(_config: FullConfig) {
HOST: "127.0.0.1",
PORT: String(PORT),
OVERLORD_TLS_OFFLOAD: "true",
OVERLORD_PUBLIC_ORIGIN: BASE_URL,
OVERLORD_WS_UPGRADE_RATE_MAX: "1000",
OVERLORD_USER: "e2e-admin",
OVERLORD_PASS: "E2ePassword!2026",
JWT_SECRET: "e2e-jwt-secret-that-is-only-used-for-browser-tests",
+9 -6
View File
@@ -1,5 +1,5 @@
<p align="center">
<img src="https://gitlab.com/vxaboveground/overlord/-/raw/main/Overlord-Server/public/assets/overlord.png" alt="Overlord" width="280" />
<img src="https://overlord.kyun.li/vxaboveground/overlord/raw/branch/main/Overlord-Server/public/assets/overlord.png" alt="Overlord" width="280" />
</p>
# Overlord
@@ -8,6 +8,8 @@
Hello, I made this project for fun.
The canonical repository is [Gitea](https://overlord.kyun.li/vxaboveground/overlord); GitLab is maintained as a mirror and release-registry host.
The server is TypeScript on Node/Bun. The client is Go. Operators talk to the server through a web panel or the Electron desktop app, and agents connect over encrypted WebSockets.
On Linux, Docker is the easiest way to run it. On Windows, a native
@@ -103,7 +105,7 @@ docker compose version
**2. Get the project**
```powershell
git clone https://gitlab.com/vxaboveground/overlord.git
git clone https://overlord.kyun.li/vxaboveground/overlord.git
cd Overlord
```
@@ -190,14 +192,14 @@ Make a folder for it, drop in the file, and you're done:
```bash
mkdir overlord && cd overlord
wget https://gitlab.com/vxaboveground/overlord/-/raw/main/docker-compose.yml
wget https://overlord.kyun.li/vxaboveground/overlord/raw/branch/main/docker-compose.yml
```
No `wget`? Use `curl`:
```bash
mkdir overlord && cd overlord
curl -O https://gitlab.com/vxaboveground/overlord/-/raw/main/docker-compose.yml
curl -O https://overlord.kyun.li/vxaboveground/overlord/raw/branch/main/docker-compose.yml
```
**3. Start it**
@@ -206,7 +208,8 @@ curl -O https://gitlab.com/vxaboveground/overlord/-/raw/main/docker-compose.yml
docker compose up -d
```
The image is pulled automatically from `registry.gitlab.com/vxaboveground/overlord:latest` on first run.
The image is currently pulled from the GitLab mirror's container registry at
`registry.gitlab.com/vxaboveground/overlord:latest` on first run.
**4. Open the panel**
@@ -266,7 +269,7 @@ docker compose version
**2. Get the project**
```bash
git clone https://gitlab.com/vxaboveground/overlord.git
git clone https://overlord.kyun.li/vxaboveground/overlord.git
cd Overlord
```
+1 -1
View File
@@ -1,6 +1,6 @@
# Build Overlord agent binaries for multiple OS/architectures
FROM golang:1.22-bookworm AS builder
LABEL org.opencontainers.image.source="https://gitlab.com/vxaboveground/overlord"
LABEL org.opencontainers.image.source="https://overlord.kyun.li/vxaboveground/overlord"
WORKDIR /src/Overlord-Client
+183
View File
@@ -0,0 +1,183 @@
# Make Gitea the primary repository
The primary repository is
<https://overlord.kyun.li/vxaboveground/overlord>. These instructions preserve
all Git branches, tags, and commits reachable from them, make Gitea the default
remote for development, and configure Gitea to push-mirror to GitLab.
This runbook targets Gitea 1.27.2. It intentionally does not use
`git push --mirror` from a working clone. A working clone contains local and
remote-tracking refs that are not part of the public branch/tag contract, and a
mirror push can also delete destination refs.
## Canonical remotes
The prepared working clone has these exact remotes:
| Name | Role | Fetch and push URL |
| --- | --- | --- |
| `origin` | Primary Gitea repository and default push target | `ssh://git@overlord.kyun.li:222/vxaboveground/overlord.git` |
| `gitlab` | Former primary; retained for comparison while the Gitea push mirror is verified | `ssh://git@altssh.gitlab.com:443/vxaboveground/overlord.git` |
| `forgejo` | Legacy internal Forgejo remote | `ssh://git@10.0.22.220:22/KDOT/Overlord-Public.git` |
`main` tracks `origin/main`, and `remote.pushDefault` is `origin`. Confirm the
local setup before the cutover:
```bash
git remote -v
git config --get branch.main.remote
git config --get branch.main.merge
git config --get remote.pushDefault
```
The expected last three values are `origin`, `refs/heads/main`, and `origin`.
Do not push directly to `gitlab` after the server-side push mirror is enabled;
Gitea must be the sole write authority.
## Copy Git history safely
1. Announce a short write freeze on GitLab. Merge or close outstanding work and
wait for running pushes to finish. Commit the migration-preparation files in
this checkout and push that commit to `gitlab/main` before taking the final
bare clone, so the new Gitea workflows and canonical links are included in
the copied history.
2. Back up the GitLab project. Create the Gitea repository at the primary URL
as an **empty** repository: do not initialize a README, license, or
`.gitignore` in Gitea.
3. From a temporary directory outside this working clone, make a bare clone of
GitLab and inspect it:
```bash
migration_dir="$(mktemp -d)"
git clone --bare \
ssh://git@altssh.gitlab.com:443/vxaboveground/overlord.git \
"$migration_dir/overlord.git"
git -C "$migration_dir/overlord.git" fsck --full
git -C "$migration_dir/overlord.git" for-each-ref \
--format='%(objectname) %(refname)' refs/heads refs/tags
```
4. Add Gitea only to that bare migration clone, then push explicit branch and
tag namespaces. These refspecs do not include remote-tracking, CI, merge
request, or other implementation-specific refs, and they do not request
deletion of destination refs:
```bash
git -C "$migration_dir/overlord.git" remote add gitea \
ssh://git@overlord.kyun.li:222/vxaboveground/overlord.git
git -C "$migration_dir/overlord.git" push --atomic gitea \
'refs/heads/*:refs/heads/*' \
'refs/tags/*:refs/tags/*'
```
A non-fast-forward rejection means Gitea already contains divergent work.
Stop and reconcile that work; do not add `--force` just to make the command
pass.
5. Compare the source and destination refs exactly:
```bash
git ls-remote --heads \
ssh://git@altssh.gitlab.com:443/vxaboveground/overlord.git \
| sort > "$migration_dir/gitlab-heads"
git ls-remote --heads \
ssh://git@overlord.kyun.li:222/vxaboveground/overlord.git \
| sort > "$migration_dir/gitea-heads"
git ls-remote --tags \
ssh://git@altssh.gitlab.com:443/vxaboveground/overlord.git \
| sort > "$migration_dir/gitlab-tags"
git ls-remote --tags \
ssh://git@overlord.kyun.li:222/vxaboveground/overlord.git \
| sort > "$migration_dir/gitea-tags"
diff -u "$migration_dir/gitlab-heads" "$migration_dir/gitea-heads"
diff -u "$migration_dir/gitlab-tags" "$migration_dir/gitea-tags"
```
Both `diff` commands should produce no output. In Gitea, set `main` as the
default branch and recreate branch/tag protection, collaborators, deploy
keys, webhooks, Actions secrets, and other host-level settings.
The explicit Git copy does not migrate GitLab issues, merge requests, comments,
release records, CI variables, job artifacts, package/container registries, or
other GitLab database content. Export/import those separately if they must be
retained. If Git LFS is enabled later, its objects also require an explicit LFS
fetch/push; ordinary ref pushes do not transfer LFS object content.
## Make Gitea the default in other clones
For an existing clone that still calls GitLab `origin`, preserve that remote
under the `gitlab` name and add Gitea as the new `origin`:
```bash
git remote rename origin gitlab
git remote add origin \
ssh://git@overlord.kyun.li:222/vxaboveground/overlord.git
git fetch origin --prune --tags
git branch --set-upstream-to=origin/main main
git config remote.pushDefault origin
```
If that clone already has a remote called `gitlab`, update URLs instead of
renaming over it:
```bash
git remote set-url origin \
ssh://git@overlord.kyun.li:222/vxaboveground/overlord.git
git remote set-url gitlab \
ssh://git@altssh.gitlab.com:443/vxaboveground/overlord.git
git fetch origin --prune --tags
git branch --set-upstream-to=origin/main main
git config remote.pushDefault origin
```
Test the cutover with a normal branch push to `origin`. Avoid configuring a
client-side push URL that writes to both hosts: the Gitea server-side mirror is
the single replication mechanism and exposes failures in its UI.
## Configure the Gitea-to-GitLab push mirror
Gitea's push mirror force-updates the destination. Once enabled, changes made
directly on GitLab may be overwritten or deleted on the next sync. Keep the
GitLab project read-only for normal development and treat it as a replica.
1. In GitLab, create a project access token or personal access token with the
`write_repository` scope. Use an account permitted to update the repository's
protected branches and tags.
2. In Gitea, open **Settings > Repository > Mirror Settings** for
`vxaboveground/overlord` and choose **Add Push Mirror**.
3. Enter these values:
- Remote repository URL: `https://gitlab.com/vxaboveground/overlord.git`
- Authorization username: `oauth2`
- Authorization password: the GitLab token
4. Enable **Sync when new commits are pushed**, add the mirror, and select
**Synchronize Now** for the initial replication.
5. Confirm that Gitea reports a successful sync, then compare heads and tags
again with the verification commands above. Make a small test branch in
Gitea, confirm it arrives in GitLab, and delete it from Gitea so the deletion
behavior is also understood before ending the write freeze.
If a sync fails, inspect the error in Gitea's Mirror Settings. The usual causes
are an expired token, missing `write_repository` permission, or GitLab protected
branch/tag rules that reject the mirror account. Rotate the GitLab credential in
Gitea rather than embedding it in a Git remote URL or this repository.
GitLab CI may run when mirrored commits arrive because this repository retains
`.gitlab-ci.yml`. Keep that behavior if GitLab remains a CI replica; otherwise
disable GitLab pipelines in the GitLab project settings after confirming Gitea
Actions covers the required jobs.
## Final checks
- `origin` fetches and pushes to Gitea over SSH port 222.
- `main` tracks `origin/main`, and `remote.pushDefault` is `origin`.
- All GitLab heads and tags match Gitea at the end of the write freeze.
- The Gitea push mirror reports a successful GitLab sync.
- Branch/tag protections, access controls, secrets, and webhooks exist in Gitea.
- The repository-scoped runner is online and a Gitea Actions workflow passes.
- Developers know Gitea is authoritative and GitLab is read-only.
After an agreed observation period, remove the legacy `forgejo` remote from
developer clones if it is no longer needed. Keep backups according to the
project's retention policy.