fix: harden repository refresh and server pull
ForgeFlow quality gate / quality (push) Canceled after 0s
ForgeFlow quality gate / quality (push) Canceled after 0s
This commit is contained in:
@@ -29,6 +29,8 @@ class RepositoryService {
|
||||
this.gitea = giteaService;
|
||||
this.diagnostics = diagnostics;
|
||||
this.lastKnownLocalPaths = [];
|
||||
this.lastKnownRemoteRepositories = [];
|
||||
this.lastSuccessfulRemoteRefreshAt = null;
|
||||
}
|
||||
|
||||
async discoverInRoot(root, maxDepth = 4) {
|
||||
@@ -80,11 +82,37 @@ class RepositoryService {
|
||||
return [...this.lastKnownLocalPaths];
|
||||
}
|
||||
|
||||
async getRemoteRepositories() {
|
||||
if (!this.store.data.gitea.baseUrl || !this.store.getToken()) {
|
||||
this.lastKnownRemoteRepositories = [];
|
||||
this.lastSuccessfulRemoteRefreshAt = null;
|
||||
return { repositories: [], stale: false, error: null };
|
||||
}
|
||||
|
||||
try {
|
||||
const repositories = await this.gitea.listRepositories();
|
||||
this.lastKnownRemoteRepositories = repositories.map((repository) => ({ ...repository }));
|
||||
this.lastSuccessfulRemoteRefreshAt = new Date().toISOString();
|
||||
return { repositories, stale: false, error: null };
|
||||
} catch (error) {
|
||||
if (!this.lastSuccessfulRemoteRefreshAt) throw error;
|
||||
await this.diagnostics?.warning('repositories.remote-refresh.degraded', {
|
||||
message: error.message,
|
||||
cachedCount: this.lastKnownRemoteRepositories.length,
|
||||
lastSuccessfulAt: this.lastSuccessfulRemoteRefreshAt
|
||||
});
|
||||
return {
|
||||
repositories: this.lastKnownRemoteRepositories.map((repository) => ({ ...repository })),
|
||||
stale: true,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
const started = Date.now();
|
||||
const remoteRepositories = this.store.data.gitea.baseUrl && this.store.getToken()
|
||||
? await this.gitea.listRepositories()
|
||||
: [];
|
||||
const remoteResult = await this.getRemoteRepositories();
|
||||
const remoteRepositories = remoteResult.repositories;
|
||||
|
||||
const discoveredPaths = await this.discoverAll(this.store.data.workspaceRoots);
|
||||
const mappedPaths = Object.values(this.store.data.repositoryMappings || {});
|
||||
@@ -106,7 +134,12 @@ class RepositoryService {
|
||||
...profile,
|
||||
state: this.store.getDeploymentState(profile.id)
|
||||
}));
|
||||
repositories.push(this.decorate(remote, local, profiles));
|
||||
repositories.push({
|
||||
...this.decorate(remote, local, profiles),
|
||||
remoteStale: remoteResult.stale,
|
||||
remoteRefreshError: remoteResult.error,
|
||||
remoteLastRefreshedAt: this.lastSuccessfulRemoteRefreshAt
|
||||
});
|
||||
}
|
||||
|
||||
for (const local of localDescriptors.filter((item) => !usedLocalPaths.has(item.localPath))) {
|
||||
@@ -145,6 +178,7 @@ class RepositoryService {
|
||||
await this.diagnostics?.debug('repositories.refresh.completed', {
|
||||
durationMs: Date.now() - started,
|
||||
remoteCount: remoteRepositories.length,
|
||||
remoteStale: remoteResult.stale,
|
||||
discoveredCount: discoveredPaths.length,
|
||||
linkedCount: sorted.filter((item) => item.localPath).length,
|
||||
attentionCount: sorted.filter((item) => item.attention).length,
|
||||
|
||||
Reference in New Issue
Block a user