* feat: add E2E testing infrastructure with fake GitHub, Playwright, and CI workflow
- Add fake GitHub API server (tests/e2e/fake-github-server.ts) with
management API for seeding test data
- Add Playwright E2E test suite covering full mirror workflow:
service health checks, user registration, config, sync, verify
- Add Docker Compose for E2E Gitea instance
- Add orchestrator script (run-e2e.sh) with cleanup
- Add GitHub Actions workflow (e2e-tests.yml) with Gitea service container
- Make GITHUB_API_URL configurable via env var for testing
- Add npm scripts: test:e2e, test:e2e:ci, test:e2e:keep, test:e2e:cleanup
* feat: add real git repos + backup config testing to E2E suite
- Create programmatic test git repos (create-test-repos.ts) with real
commits, branches (main, develop, feature/*), and tags (v1.0.0, v1.1.0)
- Add git-server container to docker-compose serving bare repos via
dumb HTTP protocol so Gitea can actually clone them
- Update fake GitHub server to emit reachable clone_url fields pointing
to the git-server container (configurable via GIT_SERVER_URL env var)
- Add management endpoint POST /___mgmt/set-clone-url for runtime config
- Update E2E spec with real mirroring verification:
* Verify repos appear in Gitea with actual content
* Check branches, tags, commits, file content
* Verify 4/4 repos mirrored successfully
- Add backup configuration test suite:
* Enable/disable backupBeforeSync config
* Toggle blockSyncOnBackupFailure
* Trigger re-sync with backup enabled and verify activities
* Verify config persistence across changes
- Update CI workflow to use docker compose (not service containers)
matching the local run-e2e.sh approach
- Update cleanup.sh for git-repos directory and git-server port
- All 22 tests passing with real git content verification
* refactor: split E2E tests into focused files + add force-push tests
Split the monolithic e2e.spec.ts (1335 lines) into 5 focused spec files
and a shared helpers module:
helpers.ts — constants, GiteaAPI, auth, saveConfig, utilities
01-health.spec.ts — service health checks (4 tests)
02-mirror-workflow.spec.ts — full first-mirror journey (8 tests)
03-backup.spec.ts — backup config toggling (6 tests)
04-force-push.spec.ts — force-push simulation & backup verification (9 tests)
05-sync-verification.spec.ts — dynamic repos, content integrity, reset (5 tests)
The force-push tests are the critical addition:
F0: Record original state (commit SHAs, file content)
F1: Rewrite source repo history (simulate force-push)
F2: Sync to Gitea WITHOUT backup
F3: Verify data loss — LICENSE file gone, README overwritten
F4: Restore source, re-mirror to clean state
F5: Enable backup, force-push again, sync through app
F6: Verify Gitea reflects the force-push
F7: Verify backup system was invoked (snapshot activities logged)
F8: Restore source repo for subsequent tests
Also added to helpers.ts:
- GiteaAPI.getBranch(), .getCommit(), .triggerMirrorSync()
- getRepositoryIds(), triggerMirrorJobs(), triggerSyncRepo()
All 32 tests passing.
* Try to fix actions
* Try to fix the other action
* Add debug info to check why e2e action is failing
* More debug info
* Even more debug info
* E2E fix attempt #1
* E2E fix attempt #2
* more debug again
* E2E fix attempt #3
* E2E fix attempt #4
* Remove a bunch of debug info
* Hopefully fix backup bug
* Force backups to succeed
* fix(nix): enable sandboxed builds with bun2nix
The Nix package was broken on Linux because `bun install` requires
network access, which is blocked by Nix sandboxing (enabled by default
on Linux).
This switches to bun2nix for dependency management:
- Add bun2nix flake input to pre-fetch all npm dependencies
- Generate bun.nix lockfile for reproducible dependency resolution
- Copy bun cache to writable location during build to avoid EACCES
errors from bunx writing to the read-only Nix store
- Add nanoid as an explicit dependency (was imported directly but only
available as a transitive dep, which breaks with isolated linker)
- Update CI workflow to perform a full sandboxed build
- Add bun2nix to devShell for easy lockfile regeneration
Closes#197
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(nix): create writable workdir for database access
The app uses process.cwd()/data for the database path, but when running
from the Nix store the cwd is read-only. Create a writable working
directory with symlinks to app files and a real data directory.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
bun install requires network access which Nix sandbox blocks.
CI now validates flake structure and evaluates expressions only.
Full builds work locally with: nix build --option sandbox false
- Use DeterminateSystems/nix-installer-action for Nix installation
- Use DeterminateSystems/magic-nix-cache-action for caching (free, no setup)
- Update documentation to remove Cachix references
- Add nix branch to CI triggers
- Added docker-entrypoint.sh to trigger paths
- Added drizzle/** for database migrations
- Added scripts/** for database management scripts
- Added src/** for source code changes
This ensures Docker images are rebuilt when critical runtime
files change, not just package dependencies.
## Problem
Forgejo 12.0+ rejects migration API calls with credentials embedded in URLs,
causing HTTP 422 errors when mirroring private GitHub repositories.
## Root Cause
Breaking security change in Forgejo 12.0 (July 2025) enforces credential
separation to prevent accidental exposure in logs/errors. Previous versions
(Forgejo 11.x, Gitea 1.x) accepted embedded credentials.
## Solution
- Use separate `auth_username` and `auth_token` fields instead of embedding
credentials in clone URLs
- Set `auth_username` to "oauth2" for GitHub token authentication
- Pass GitHub token via `auth_token` field
## Changes
- src/lib/gitea.ts:
- mirrorGithubRepoToGitea(): Use separate auth fields for private repos
- mirrorGitHubRepoToGiteaOrg(): Use separate auth fields for private repos
- .github/workflows/docker-build.yml:
- Enable PR image building and pushing to GHCR
- Tag PR images as pr-<number> for easy testing
- Add automated PR comment with image details and testing instructions
- Separate load step for security scanning
## Backward Compatibility
✅ Works with Forgejo 12.0+
✅ Works with Forgejo 11.x and earlier
✅ Works with Gitea 1.x
## Testing
Public repos: ✅ Working (no auth needed)
Private repos: ✅ Fixed (separate auth fields)
Fixes#102
- Update Bun version in CI to match local version (1.2.16)
- Add bunfig.toml with 5s test timeout to prevent hanging tests
- Mock setTimeout globally in test setup to avoid timing issues
- Add NODE_ENV check to skip delays during tests
- Fix missing exports in config-encryption mock
- Remove retryDelay in tests to ensure immediate execution
These changes ensure tests run consistently between local and CI environments
- Use specific SHA-based image tags instead of multi-line tags output
- Add separate Docker Scout steps for push vs pull request workflows
- Use local image reference for PR scanning (local://gitea-mirror:scan)
- Optimize PR builds to single platform (linux/amd64) for faster scanning
- Maintain multi-platform builds for production pushes
- Add optional Docker Hub login for enhanced vulnerability data
- Use continue-on-error to make Docker Hub auth optional
- Requires DOCKERHUB_USERNAME and DOCKERHUB_TOKEN secrets for full functionality
- Update Bun from 1.2.14 to 1.2.18 to address CVE-2025-22874
- Pin Trivy action to stable version (0.28.0)
- Add SARIF output for GitHub Security tab integration
- Set ignore-unfixed to false for comprehensive vulnerability detection
- Add security-events permission for uploading scan results
- Include fallback table output on scan failures
- Updated GitHub Actions workflow to use Bun's test runner and coverage reporting.
- Added comprehensive testing documentation for the Gitea Mirror project.
- Refactored test scripts in package.json to align with Bun's testing commands.
- Created new test files for database, Gitea, GitHub, health, and mirroring APIs.
- Implemented mock functions for API tests to handle various scenarios and responses.
- Established a test setup file for consistent test environment configuration.