Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9feb49a3d4 | |||
| 879f16dd98 | |||
| e94004742f | |||
| 82940c7c0f | |||
| 016eaf1b91 | |||
| cbb9f364ae | |||
| ef688115d6 | |||
| 3aaa0f7e68 |
32
changelog.md
32
changelog.md
@@ -1,5 +1,37 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-03-02 - 2.4.0 - feat(gitlab)
|
||||||
|
add repository branches and tags endpoints and corresponding types
|
||||||
|
|
||||||
|
- Add getRepoBranches(projectId, opts?) to list repository branches (supports pagination with page and perPage; defaults to page=1, perPage=50).
|
||||||
|
- Add getRepoTags(projectId, opts?) to list repository tags (supports pagination with page and perPage; defaults to page=1, perPage=50).
|
||||||
|
- Introduce IGitLabBranch and IGitLabTag interfaces and export them from ts/index.ts.
|
||||||
|
|
||||||
|
## 2026-02-28 - 2.3.0 - feat(gitlab)
|
||||||
|
add support for GitLab protected branches (list and unprotect)
|
||||||
|
|
||||||
|
- Added IGitLabProtectedBranch interface
|
||||||
|
- Added GitLabClient.getProtectedBranches(projectId) returning IGitLabProtectedBranch[]
|
||||||
|
- Added GitLabClient.unprotectBranch(projectId, branchName) to remove branch protection
|
||||||
|
- Exported IGitLabProtectedBranch from index.ts
|
||||||
|
- Non-breaking API additions; recommended minor version bump
|
||||||
|
|
||||||
|
## 2026-02-28 - 2.2.0 - feat(gitlabclient)
|
||||||
|
add deleteProject method to delete a project using GitLab API DELETE /api/v4/projects/:id
|
||||||
|
|
||||||
|
- Adds GitlabClient.deleteProject(projectId: number | string): Promise<void>.
|
||||||
|
- Implements DELETE /api/v4/projects/:id and URL-encodes the projectId.
|
||||||
|
- Non-breaking API addition — bump minor version.
|
||||||
|
|
||||||
|
## 2026-02-28 - 2.1.0 - feat(gitlab)
|
||||||
|
add group- and project-management methods to GitLab client
|
||||||
|
|
||||||
|
- Adds getGroupByPath(fullPath) to fetch a group by full path
|
||||||
|
- Adds getGroupProjects(groupId, opts?) to list projects in a group (include_subgroups=true, default perPage=50, optional search)
|
||||||
|
- Adds getDescendantGroups(groupId, opts?) to list descendant subgroups (paginated, default perPage=50, optional search)
|
||||||
|
- Adds createGroup(name, path, parentId?) to create groups (defaults to private visibility)
|
||||||
|
- Adds createProject(name, opts?) to create projects with optional path, namespaceId, visibility (default private) and description
|
||||||
|
|
||||||
## 2026-02-24 - 2.0.3 - fix()
|
## 2026-02-24 - 2.0.3 - fix()
|
||||||
no changes detected; nothing to commit
|
no changes detected; nothing to commit
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@apiclient.xyz/gitlab",
|
"name": "@apiclient.xyz/gitlab",
|
||||||
"version": "2.0.3",
|
"version": "2.4.0",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "A TypeScript client for the GitLab API, providing easy access to projects, groups, CI/CD variables, and pipelines.",
|
"description": "A TypeScript client for the GitLab API, providing easy access to projects, groups, CI/CD variables, and pipelines.",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@apiclient.xyz/gitlab',
|
name: '@apiclient.xyz/gitlab',
|
||||||
version: '2.0.3',
|
version: '2.4.0',
|
||||||
description: 'A TypeScript client for the GitLab API, providing easy access to projects, groups, CI/CD variables, and pipelines.'
|
description: 'A TypeScript client for the GitLab API, providing easy access to projects, groups, CI/CD variables, and pipelines.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import type {
|
|||||||
IGitLabGroup,
|
IGitLabGroup,
|
||||||
IGitLabVariable,
|
IGitLabVariable,
|
||||||
IVariableOptions,
|
IVariableOptions,
|
||||||
|
IGitLabProtectedBranch,
|
||||||
|
IGitLabBranch,
|
||||||
|
IGitLabTag,
|
||||||
IGitLabPipeline,
|
IGitLabPipeline,
|
||||||
IGitLabJob,
|
IGitLabJob,
|
||||||
ITestConnectionResult,
|
ITestConnectionResult,
|
||||||
@@ -125,6 +128,73 @@ export class GitLabClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Groups — scoped queries
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single group by its full path (e.g. "foss.global" or "foss.global/push.rocks")
|
||||||
|
*/
|
||||||
|
public async getGroupByPath(fullPath: string): Promise<IGitLabGroup> {
|
||||||
|
return this.request<IGitLabGroup>(
|
||||||
|
'GET',
|
||||||
|
`/api/v4/groups/${encodeURIComponent(fullPath)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List projects within a group (includes subgroups when include_subgroups=true)
|
||||||
|
*/
|
||||||
|
public async getGroupProjects(groupId: number | string, opts?: IListOptions): Promise<IGitLabProject[]> {
|
||||||
|
const page = opts?.page || 1;
|
||||||
|
const perPage = opts?.perPage || 50;
|
||||||
|
let url = `/api/v4/groups/${encodeURIComponent(groupId)}/projects?include_subgroups=true&order_by=updated_at&sort=desc&page=${page}&per_page=${perPage}`;
|
||||||
|
if (opts?.search) {
|
||||||
|
url += `&search=${encodeURIComponent(opts.search)}`;
|
||||||
|
}
|
||||||
|
return this.request<IGitLabProject[]>('GET', url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all descendant groups (recursive subgroups) within a group
|
||||||
|
*/
|
||||||
|
public async getDescendantGroups(groupId: number | string, opts?: IListOptions): Promise<IGitLabGroup[]> {
|
||||||
|
const page = opts?.page || 1;
|
||||||
|
const perPage = opts?.perPage || 50;
|
||||||
|
let url = `/api/v4/groups/${encodeURIComponent(groupId)}/descendant_groups?order_by=name&sort=asc&page=${page}&per_page=${perPage}`;
|
||||||
|
if (opts?.search) {
|
||||||
|
url += `&search=${encodeURIComponent(opts.search)}`;
|
||||||
|
}
|
||||||
|
return this.request<IGitLabGroup[]>('GET', url);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new group. Optionally nested under a parent group.
|
||||||
|
*/
|
||||||
|
public async createGroup(name: string, path: string, parentId?: number): Promise<IGitLabGroup> {
|
||||||
|
const body: any = { name, path, visibility: 'private' };
|
||||||
|
if (parentId) body.parent_id = parentId;
|
||||||
|
return this.request<IGitLabGroup>('POST', '/api/v4/groups', body);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new project (repository).
|
||||||
|
*/
|
||||||
|
public async createProject(name: string, opts?: {
|
||||||
|
path?: string;
|
||||||
|
namespaceId?: number;
|
||||||
|
visibility?: string;
|
||||||
|
description?: string;
|
||||||
|
}): Promise<IGitLabProject> {
|
||||||
|
return this.request<IGitLabProject>('POST', '/api/v4/projects', {
|
||||||
|
name,
|
||||||
|
path: opts?.path || name,
|
||||||
|
namespace_id: opts?.namespaceId,
|
||||||
|
visibility: opts?.visibility || 'private',
|
||||||
|
description: opts?.description || '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Projects
|
// Projects
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -301,4 +371,55 @@ export class GitLabClient {
|
|||||||
`/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/cancel`,
|
`/api/v4/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/cancel`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Repository Branches & Tags
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public async getRepoBranches(projectId: number | string, opts?: IListOptions): Promise<IGitLabBranch[]> {
|
||||||
|
const page = opts?.page || 1;
|
||||||
|
const perPage = opts?.perPage || 50;
|
||||||
|
return this.request<IGitLabBranch[]>(
|
||||||
|
'GET',
|
||||||
|
`/api/v4/projects/${encodeURIComponent(projectId)}/repository/branches?page=${page}&per_page=${perPage}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getRepoTags(projectId: number | string, opts?: IListOptions): Promise<IGitLabTag[]> {
|
||||||
|
const page = opts?.page || 1;
|
||||||
|
const perPage = opts?.perPage || 50;
|
||||||
|
return this.request<IGitLabTag[]>(
|
||||||
|
'GET',
|
||||||
|
`/api/v4/projects/${encodeURIComponent(projectId)}/repository/tags?page=${page}&per_page=${perPage}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Protected Branches
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public async getProtectedBranches(projectId: number | string): Promise<IGitLabProtectedBranch[]> {
|
||||||
|
return this.request<IGitLabProtectedBranch[]>(
|
||||||
|
'GET',
|
||||||
|
`/api/v4/projects/${encodeURIComponent(projectId)}/protected_branches`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async unprotectBranch(projectId: number | string, branchName: string): Promise<void> {
|
||||||
|
await this.request(
|
||||||
|
'DELETE',
|
||||||
|
`/api/v4/projects/${encodeURIComponent(projectId)}/protected_branches/${encodeURIComponent(branchName)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Project Deletion
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public async deleteProject(projectId: number | string): Promise<void> {
|
||||||
|
await this.request(
|
||||||
|
'DELETE',
|
||||||
|
`/api/v4/projects/${encodeURIComponent(projectId)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ export interface IVariableOptions {
|
|||||||
environment_scope?: string;
|
environment_scope?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IGitLabProtectedBranch {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
allow_force_push: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IGitLabPipeline {
|
export interface IGitLabPipeline {
|
||||||
id: number;
|
id: number;
|
||||||
project_id: number;
|
project_id: number;
|
||||||
@@ -64,6 +70,20 @@ export interface IGitLabJob {
|
|||||||
duration: number;
|
duration: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IGitLabBranch {
|
||||||
|
name: string;
|
||||||
|
commit: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IGitLabTag {
|
||||||
|
name: string;
|
||||||
|
commit: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface ITestConnectionResult {
|
export interface ITestConnectionResult {
|
||||||
ok: boolean;
|
ok: boolean;
|
||||||
error?: string;
|
error?: string;
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ export type {
|
|||||||
IGitLabProject,
|
IGitLabProject,
|
||||||
IGitLabGroup,
|
IGitLabGroup,
|
||||||
IGitLabVariable,
|
IGitLabVariable,
|
||||||
|
IGitLabProtectedBranch,
|
||||||
|
IGitLabBranch,
|
||||||
|
IGitLabTag,
|
||||||
IVariableOptions,
|
IVariableOptions,
|
||||||
IGitLabPipeline,
|
IGitLabPipeline,
|
||||||
IGitLabJob,
|
IGitLabJob,
|
||||||
|
|||||||
Reference in New Issue
Block a user