You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Real-provider testing has already caught provider/API behavior that mocked requestUrl cannot reliably cover. The repository supports GitHub, GitLab, and Gitea, so this issue remains the foundation for headless real-provider integration testing.
Previous E2E infrastructure also exposed an important constraint: Node-only test harness code (fetch, globalThis, node:crypto, node:child_process, node:util) can be picked up by the Obsidian scanner even though it is test-only. The revised design keeps those responsibilities out of the plugin TypeScript test surface.
Goal
Run production provider code against real GitHub / GitLab / Gitea repositories with isolated test branches, independent remote verification, and cleanup that remains safe under concurrency and cancellation.
flowchart LR
CI[GitHub Actions] --> P[Shell harness: provision]
P --> R[(Dedicated test repo)]
CI --> T[TypeScript integration tests]
T --> S[Production provider service]
S --> R
R --> V[Shell harness: independent verify]
V --> C[Shell harness: cleanup]
Loading
Responsibility boundary
Shell / CI harness
Use Shell + standard Git CLI for test-environment work:
Use gh / glab only when provider-specific API behavior cannot be expressed cleanly with standard Git. Keep Docker/service startup for Gitea at the GitHub Actions layer rather than spawning it from Node.
Do not reintroduce Node-only provisioning/verifier scripts into the plugin E2E suite.
TypeScript integration tests
TypeScript tests should only exercise the code under test:
instantiate the real production provider service;
testConnection;
list/read/push/update/delete;
batch operations;
move/rename semantics;
conflict/concurrency protections;
root-path handling and provider-specific behavior.
Independent verification must not reuse the provider implementation under test.
Git authentication
CI secrets should be injected as job-scoped environment variables and exposed to Git through GIT_ASKPASS.
Do not:
embed tokens in remote URLs;
persist tokens into .git/config;
pass tokens as normal CLI arguments;
print tokens in logs or artifacts.
The askpass helper contains no credential itself; it only reads the job-scoped environment value when Git requests authentication.
Branch isolation
Every provider job receives a unique remote branch. A cancelled/stuck run must never share state with a newer run.
Context
Real-provider testing has already caught provider/API behavior that mocked
requestUrlcannot reliably cover. The repository supports GitHub, GitLab, and Gitea, so this issue remains the foundation for headless real-provider integration testing.Previous E2E infrastructure also exposed an important constraint: Node-only test harness code (
fetch,globalThis,node:crypto,node:child_process,node:util) can be picked up by the Obsidian scanner even though it is test-only. The revised design keeps those responsibilities out of the plugin TypeScript test surface.Goal
Run production provider code against real GitHub / GitLab / Gitea repositories with isolated test branches, independent remote verification, and cleanup that remains safe under concurrency and cancellation.
flowchart LR CI[GitHub Actions] --> P[Shell harness: provision] P --> R[(Dedicated test repo)] CI --> T[TypeScript integration tests] T --> S[Production provider service] S --> R R --> V[Shell harness: independent verify] V --> C[Shell harness: cleanup]Responsibility boundary
Shell / CI harness
Use Shell + standard Git CLI for test-environment work:
Use
gh/glabonly when provider-specific API behavior cannot be expressed cleanly with standard Git. Keep Docker/service startup for Gitea at the GitHub Actions layer rather than spawning it from Node.Do not reintroduce Node-only provisioning/verifier scripts into the plugin E2E suite.
TypeScript integration tests
TypeScript tests should only exercise the code under test:
testConnection;Independent verification must not reuse the provider implementation under test.
Git authentication
CI secrets should be injected as job-scoped environment variables and exposed to Git through
GIT_ASKPASS.Do not:
.git/config;The askpass helper contains no credential itself; it only reads the job-scoped environment value when Git requests authentication.
Branch isolation
Every provider job receives a unique remote branch. A cancelled/stuck run must never share state with a newer run.
PR run:
Branch-only run:
Identity should include:
github.run_id;github.run_attempt.Cleanup lifecycle
Cleanup is best-effort; correctness must not depend on cleanup always running.
Per-job cleanup
if: always();PR / source-branch lifecycle cleanup
e2e/pr/<number>/**;e2e/branch/<name>/**namespace.Scheduled janitor
e2e/**branches older than a TTL;A new run always allocates a new branch, so an orphan from an older run is harmless until the janitor removes it.
CI shape
Keep provider and Obsidian compatibility matrices independent. This issue owns the provider matrix only:
Each provider job follows the same lifecycle:
Do not create an Obsidian-version × provider Cartesian matrix.
Provider contract coverage
Shared scenarios
testConnectionpushFilecreate/updategetFilepushBatchdeleteFiledeleteBatchlistFilesDetailedgetBlobGitHub additional scenarios
errors[]handlingmode 120000)Acceptance criteria
Follow-up
GUI/real-Obsidian automation remains tracked separately in #115 and should reuse this provider sandbox/lifecycle rather than duplicate it.