Add Gitea integration; fix .env never being loaded outside Docker
Second live integration: repo list with last CI run status, and re-running
failed jobs on a workflow run — matching the "dashboard + basic actions"
depth from the plan. Adapter built directly against the real Gitea 1.27
swagger spec (fetched from the user's own instance) rather than guessing at
the API shape: GET /user/repos for the repo list, GET
/repos/{owner}/{repo}/actions/runs?limit=1 for the latest run per repo (only
for repos with Actions enabled), and POST .../rerun-failed-jobs for retrying
just the failed jobs in a run. Follows the same config-in-UI +
encrypted-credential pattern as Tailscale and DNS providers.
Since Gitea collects its own base URL as a config field (unlike Tailscale,
which always talks to a fixed api.tailscale.com), generalized the
"integrations.baseUrl" bookkeeping into resolveBaseUrl() instead of the
one-fixed-URL-per-type map used previously.
Also fixed a real gap found while setting this up: server/src/env.ts reads
process.env directly, but nothing in the app ever loaded .env into
process.env for plain `node dist/index.js` / `tsx src/index.ts` runs — only
Docker's `env_file` config populated it, by injecting vars before Node even
starts. Every local (non-Docker) run silently had every setting at its
insecure default. Added server/src/loadEnv.ts (dotenv, pointed at the
repo-root .env) as the first import in both server/src/index.ts and
server/src/db/migrate.ts's standalone entrypoint.
Verified against the user's real, reachable services — not mocks:
- Authentik (auth.labsconnect.se): full OIDC login completed by the user
through the real UI; confirmed their account landed as admin (first user).
- Gitea (gitea.labsconnect.se): the compiled adapter run directly against a
real API token correctly listed all 11 real repos; a full HTTP-layer test
against the live server (8 checks) additionally covered a real
test-connection ping, credential non-leakage in list responses, and role
gating (403) on the rerun-failed-jobs action even with a valid token
behind it. None of the real repos have any workflow run history yet, so
the success/failure status badge and the rerun action itself are
implemented per the swagger spec but not yet exercised against a real run
— worth checking once one of those repos has actual CI activity.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
069225c656
commit
79710aa7a5
12 files changed
+479
-6
No files matched your search
@@ -198,6 +198,30 @@ export interface TailscaleDevicesResponse {
|
||||
summary: { total: number; online: number; unauthorized: number };
|
||||
}
|
||||
|
||||
export interface GiteaWorkflowRun {
|
||||
id: number;
|
||||
displayTitle: string;
|
||||
status: string;
|
||||
conclusion: string | null;
|
||||
headBranch: string;
|
||||
event: string;
|
||||
runNumber: number;
|
||||
htmlUrl: string;
|
||||
startedAt: string | null;
|
||||
completedAt: string | null;
|
||||
}
|
||||
|
||||
export interface GiteaRepo {
|
||||
owner: string;
|
||||
name: string;
|
||||
fullName: string;
|
||||
htmlUrl: string;
|
||||
private: boolean;
|
||||
hasActions: boolean;
|
||||
updatedAt: string;
|
||||
latestRun: GiteaWorkflowRun | null;
|
||||
}
|
||||
|
||||
export class UnauthorizedError extends Error {}
|
||||
export class ForbiddenError extends Error {}
|
||||
|
||||
@@ -368,5 +392,13 @@ export const api = {
|
||||
method: "DELETE",
|
||||
}),
|
||||
},
|
||||
gitea: {
|
||||
repos: (integrationId: number) => request<{ repos: GiteaRepo[] }>(`/api/integrations/${integrationId}/gitea/repos`),
|
||||
rerunFailed: (integrationId: number, owner: string, repo: string, runId: number) =>
|
||||
request<void>(
|
||||
`/api/integrations/${integrationId}/gitea/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/runs/${runId}/rerun-failed`,
|
||||
{ method: "POST" },
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
Reference in new issue
Block a user