paginate app operations and refine runtime settings layout
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -34,6 +34,8 @@ export class GiteaService {
|
||||
private readonly baseUrl: string;
|
||||
private readonly appOrg: string;
|
||||
private readonly token?: string;
|
||||
private readonly releaseBranchPushUsers: string[];
|
||||
private readonly releaseBranchMergeUsers: string[];
|
||||
|
||||
constructor(configService: ConfigService) {
|
||||
this.baseUrl = configService
|
||||
@@ -41,6 +43,12 @@ export class GiteaService {
|
||||
.replace(/\/$/, '');
|
||||
this.appOrg = configService.get<string>('GITEA_APP_ORG', 'platform');
|
||||
this.token = configService.get<string>('GITEA_ADMIN_TOKEN') || undefined;
|
||||
this.releaseBranchPushUsers = parseWhiteList(
|
||||
configService.get<string>('GITEA_RELEASE_PUSH_WHITELIST'),
|
||||
);
|
||||
this.releaseBranchMergeUsers = parseWhiteList(
|
||||
configService.get<string>('GITEA_RELEASE_MERGE_WHITELIST'),
|
||||
);
|
||||
}
|
||||
|
||||
async getVersion() {
|
||||
@@ -159,6 +167,10 @@ export class GiteaService {
|
||||
await this.createDefaultBranches(repo.owner.login, repo.name, repo.default_branch, body);
|
||||
}
|
||||
|
||||
if (body.createReleaseBranch !== false) {
|
||||
await this.protectReleaseBranch(repo.owner.login, repo.name);
|
||||
}
|
||||
|
||||
return { repo: mapRepo(repo), branches: await this.listBranches(repo.owner.login, repo.name) };
|
||||
}
|
||||
|
||||
@@ -174,6 +186,10 @@ export class GiteaService {
|
||||
await this.createDefaultBranches(org, repo.name, repo.default_branch, body);
|
||||
}
|
||||
|
||||
if (body.createReleaseBranch !== false) {
|
||||
await this.protectReleaseBranch(org, repo.name);
|
||||
}
|
||||
|
||||
return { repo: mapRepo(repo), branches: await this.listBranches(org, repo.name) };
|
||||
}
|
||||
|
||||
@@ -241,6 +257,42 @@ export class GiteaService {
|
||||
return createdBranches;
|
||||
}
|
||||
|
||||
private async protectReleaseBranch(owner: string, repo: string) {
|
||||
const me = await this.getAuthenticatedUser();
|
||||
const pushUsernames = uniqueUsers([
|
||||
...this.releaseBranchPushUsers,
|
||||
...(me?.login ? [me.login] : []),
|
||||
]);
|
||||
const mergeUsernames = uniqueUsers([
|
||||
...this.releaseBranchMergeUsers,
|
||||
...(me?.login ? [me.login] : []),
|
||||
]);
|
||||
|
||||
const body = {
|
||||
branch_name: 'release',
|
||||
enable_push: true,
|
||||
enable_push_whitelist: true,
|
||||
push_whitelist_usernames: pushUsernames,
|
||||
enable_merge_whitelist: true,
|
||||
merge_whitelist_usernames: mergeUsernames,
|
||||
enable_force_push: false,
|
||||
};
|
||||
|
||||
await this.request(`/api/v1/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/branch_protections`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(body),
|
||||
allowedStatuses: [409],
|
||||
});
|
||||
}
|
||||
|
||||
private async getAuthenticatedUser() {
|
||||
try {
|
||||
return await this.request<{ login: string }>('/api/v1/user');
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private async request<T>(
|
||||
path: string,
|
||||
init?: RequestInit & { allowedStatuses?: number[] },
|
||||
@@ -373,6 +425,30 @@ function mapRepo(repo: GiteaRepo) {
|
||||
};
|
||||
}
|
||||
|
||||
function parseWhiteList(raw?: string) {
|
||||
if (!raw) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return raw
|
||||
.split(',')
|
||||
.map((value) => value.trim())
|
||||
.filter((value) => value.length > 0);
|
||||
}
|
||||
|
||||
function uniqueUsers(values: string[]) {
|
||||
const seen = new Set<string>();
|
||||
const next: string[] = [];
|
||||
|
||||
for (const value of values) {
|
||||
if (seen.has(value)) continue;
|
||||
seen.add(value);
|
||||
next.push(value);
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
function toCreateRepoPayload(body: CreateGiteaRepoDto) {
|
||||
return {
|
||||
name: body.name,
|
||||
|
||||
Reference in New Issue
Block a user