Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ipaas/public/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
"AI_COPILOT_BLOG_URL": "https://wso2.com/library/blogs/introducing-choreo-copilot/",
"GITHUB_APP_CLIENT_ID": "Iv1.f6cf2cd585148ee7",
"GITHUB_APP_AUTH_REDIRECTION_URL": "",
"GITHUB_APP_SLUG": "wso2-cloud-app-dev",
"AVAILABLE_LOGIN_REGIONS": "US::https://localhost:3000,EU::https://console.dv.eu.devant.dev"
}
8 changes: 7 additions & 1 deletion ipaas/src/api/cloud/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@

/** Cloud (OpenChoreo) project API. Calls the ipaas-service BFF. */

import type { Project, ProjectContributor, ProjectHandlerAvailability, CreateProjectInput, CreateMonoRepoProjectInput, UpdateProjectInput } from '../../types/project';
import type { Project, ProjectContributor, ProjectHandlerAvailability, CreateProjectInput, CreateMonoRepoProjectInput, LinkProjectRepositoryInput, UpdateProjectInput } from '../../types/project';
import { bff, items, q, seg, type ListResponse } from './_client';

const ni = (name: string): never => {
throw new Error(`[cloud] projects.${name}: not implemented`);
};

// _orgId is kept on the signatures for devant contract parity; cloud derives
// the org from the access token instead of taking a numeric id from the caller.

Expand Down Expand Up @@ -93,3 +97,5 @@ export const updateProject = (input: UpdateProjectInput): Promise<Project> => bf
export const deleteProject = (projectId: string): Promise<void> => bff.delete<void>(`/projects/${seg(projectId)}`);

export const createMonoRepoProject = async (input: CreateMonoRepoProjectInput): Promise<Project> => bff.post<Project>('/projects', await toBffCreateMonoRepoProjectBody(input));

export const linkProjectRepository = (_input: LinkProjectRepositoryInput): Promise<Project> => ni('linkProjectRepository');
11 changes: 6 additions & 5 deletions ipaas/src/api/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ import type { ApiDocument, RuleAdherenceResponse, ThrottlingPolicy } from '../ty
import type { CreateMcpApiInput, CreatedMcpApi, McpFeatureOperation, McpProxyMetadata, CreateMcpProxyComponentInput } from '../types/mcpProxy';
import type { OrgEntry, OrgComponentLimits, OrgSubscription, RegisterUserResponse } from '../types/org';
import type { PrebuiltIntegrationsData, PrebuiltComponentRef, PrebuiltEnvironmentRef } from '../types/prebuilt';
import type { Project, ProjectContributor, ProjectHandlerAvailability, CreateProjectInput, CreateMonoRepoProjectInput, UpdateProjectInput } from '../types/project';
import type { Project, ProjectContributor, ProjectHandlerAvailability, CreateProjectInput, CreateMonoRepoProjectInput, LinkProjectRepositoryInput, UpdateProjectInput } from '../types/project';
import type { Repository, Commit, UserRepo, RepoBranch, RepoMetadata, RepoTreeNode, ChoreoSampleImageEntry } from '../types/repository';
import type { Sample } from '../types/samples';

Expand Down Expand Up @@ -638,6 +638,7 @@ export interface ProjectsApi {
fetchProjectHandlerAvailability(orgId: number, candidate: string): Promise<ProjectHandlerAvailability>;
createProject(input: CreateProjectInput): Promise<Project>;
createMonoRepoProject(input: CreateMonoRepoProjectInput): Promise<Project>;
linkProjectRepository(input: LinkProjectRepositoryInput): Promise<Project>;
updateProject(input: UpdateProjectInput): Promise<Project>;
deleteProject(projectId: string): Promise<void>;
}
Expand All @@ -649,9 +650,9 @@ export interface ProjectsApi {
export interface RepositoryApi {
fetchComponentRepository(projectId: string, componentHandler: string): Promise<Repository | null>;
fetchCommitHistory(componentId: string, branch: string): Promise<Commit[]>;
fetchGitHubUserRepos(): Promise<UserRepo[]>;
fetchRepoBranches(repoOrg: string, repoName: string, isPublicRepo: boolean): Promise<RepoBranch[]>;
fetchRepoMetadata(org: string, repo: string, branch: string, subPath: string, isPublicRepo?: boolean): Promise<RepoMetadata>;
fetchGitHubUserRepos(secretRef?: string): Promise<UserRepo[]>;
fetchRepoBranches(repoOrg: string, repoName: string, isPublicRepo: boolean, secretRef?: string): Promise<RepoBranch[]>;
fetchRepoMetadata(org: string, repo: string, branch: string, subPath: string, isPublicRepo?: boolean, secretRef?: string): Promise<RepoMetadata>;
fetchChoreoSampleImages(orgUuid: string, projectId: string): Promise<ChoreoSampleImageEntry[]>;
updateBuildpackConfigs(input: UpdateBuildpackConfigsInput): Promise<string>;
/**
Expand All @@ -660,7 +661,7 @@ export interface RepositoryApi {
* account" — the UI should open the App installation page.
*/
obtainGithubToken(authorizationCode: string): Promise<{ success: boolean; message: string; needsInstallation?: boolean }>;
fetchRepoContents(org: string, repo: string, branch: string, isPublicRepo?: boolean): Promise<RepoTreeNode[]>;
fetchRepoContents(org: string, repo: string, branch: string, isPublicRepo?: boolean, secretRef?: string): Promise<RepoTreeNode[]>;
}

// ---------------------------------------------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion ipaas/src/api/icp/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

// TODO: implement using ICP local REST APIs

import type { Project, ProjectContributor, ProjectHandlerAvailability, CreateProjectInput, CreateMonoRepoProjectInput, UpdateProjectInput } from '../../types/project';
import type { Project, ProjectContributor, ProjectHandlerAvailability, CreateProjectInput, CreateMonoRepoProjectInput, LinkProjectRepositoryInput, UpdateProjectInput } from '../../types/project';

const ni = (name: string): never => {
throw new Error(`[icp] projects.${name}: not implemented`);
Expand All @@ -32,5 +32,6 @@ export const fetchProjectComponentLabels = (_orgId: number, _projectId: string):
export const fetchProjectHandlerAvailability = (_orgId: number, _candidate: string): Promise<ProjectHandlerAvailability> => ni('fetchProjectHandlerAvailability');
export const createProject = (_input: CreateProjectInput): Promise<Project> => ni('createProject');
export const createMonoRepoProject = (_input: CreateMonoRepoProjectInput): Promise<Project> => ni('createMonoRepoProject');
export const linkProjectRepository = (_input: LinkProjectRepositoryInput): Promise<Project> => ni('linkProjectRepository');
export const updateProject = (_input: UpdateProjectInput): Promise<Project> => ni('updateProject');
export const deleteProject = (_projectId: string): Promise<void> => ni('deleteProject');
2 changes: 1 addition & 1 deletion ipaas/src/api/wip/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function buildCreateComponentQuery(input: CreateComponentInput): string {
repositoryType: "UserManagedNonEmpty",
repositoryBranch: ${gqlStr(input.repositoryBranch ?? '')},
initializeAsBallerinaProject: false,
secretRef: "",
secretRef: ${gqlStr(input.secretRef ?? '')},
isPublicRepo: ${input.isPublicRepo ?? false},
enableAutoDeploy: ${input.enableAutoDeploy ?? true},
enableAutoBuild: true,
Expand Down
2 changes: 1 addition & 1 deletion ipaas/src/api/wip/credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { GitProvider, type CreateGitCredentialInput, type CredentialDeleteEligib
// are interpolated into the document, so escape any quotes/backslashes/newlines.
const orgUuid = () => getOrgUuidFromToken() ?? '';
const esc = (s: string) => s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
const CRED_FIELDS = 'id name createdAt organizationUuid type referenceToken';
const CRED_FIELDS = 'id name createdAt organizationUuid type referenceToken serverUrl';

function providerConfig(input: CreateGitCredentialInput): string {
switch (input.type) {
Expand Down
53 changes: 50 additions & 3 deletions ipaas/src/api/wip/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

import { gql } from './graphql';
import type { Project, ProjectContributor, ProjectHandlerAvailability, CreateProjectInput, CreateMonoRepoProjectInput, UpdateProjectInput } from '../../types/project';
import type { Project, ProjectContributor, ProjectHandlerAvailability, CreateProjectInput, CreateMonoRepoProjectInput, LinkProjectRepositoryInput, UpdateProjectInput } from '../../types/project';

const PROJECT_FIELDS = 'id, orgId, name, handler, description, version, createdDate, updatedAt, region, type, defaultDeploymentPipelineId, gitOrganization, repository, branch, gitProvider';

Expand Down Expand Up @@ -80,7 +80,7 @@ const CREATE_MONO_REPO_PROJECT = `
$name: String!, $description: String!, $projectHandler: String!,
$orgHandler: String!, $orgId: Int!,
$repository: String!, $gitOrganization: String!, $branch: String!,
$directoryPath: String!, $gitProvider: String!, $isPublicRepo: Boolean!
$directoryPath: String!, $gitProvider: String!, $isPublicRepo: Boolean!, $secretRef: String!
) {
createProject(project: {
name: $name,
Expand All @@ -90,7 +90,7 @@ const CREATE_MONO_REPO_PROJECT = `
orgHandler: $orgHandler,
version: "1.0.0",
repository: $repository,
secretRef: "",
secretRef: $secretRef,
branch: $branch,
gitProvider: $gitProvider,
gitOrganization: $gitOrganization,
Expand All @@ -103,6 +103,34 @@ const CREATE_MONO_REPO_PROJECT = `
}
}`;

const CREATE_PROJECT_REPOSITORY = `
mutation CreateProjectRepository(
$name: String!, $description: String!, $projectHandler: String!,
$orgHandler: String!, $orgId: Int!, $projectId: String!,
$repository: String!, $secretRef: String!, $gitOrganization: String!,
$branch: String!, $directoryPath: String!, $gitProvider: String!, $isPublicRepo: Boolean!
) {
createProjectRepository(project: {
name: $name,
description: $description,
projectHandler: $projectHandler,
orgId: $orgId,
orgHandler: $orgHandler,
version: "1.0.0",
repository: $repository,
secretRef: $secretRef,
branch: $branch,
gitProvider: $gitProvider,
gitOrganization: $gitOrganization,
directoryPath: $directoryPath,
isPublicRepo: $isPublicRepo
}, projectId: $projectId) {
id, orgId, name, version, createdDate, handler, region,
description, defaultDeploymentPipelineId, deploymentPipelineIds,
type, updatedAt, branch, repository, gitProvider, gitOrganization
}
}`;

export async function fetchProjects(orgId: number): Promise<Project[]> {
return gql<{ projects: Project[] }>(PROJECTS_QUERY, { orgId }).then((d) => d.projects ?? []);
}
Expand Down Expand Up @@ -180,5 +208,24 @@ export async function createMonoRepoProject(input: CreateMonoRepoProjectInput):
directoryPath: input.directoryPath,
gitProvider: input.gitProvider,
isPublicRepo: input.isPublicRepo,
secretRef: input.secretRef ?? '',
}).then((d) => d.createProject);
}

export async function linkProjectRepository(input: LinkProjectRepositoryInput): Promise<Project> {
return gql<{ createProjectRepository: Project }>(CREATE_PROJECT_REPOSITORY, {
name: input.name,
description: input.description,
projectHandler: input.handler,
orgHandler: input.orgHandler,
orgId: orgNumericId(),
projectId: input.projectId,
repository: input.repository,
secretRef: input.secretRef,
gitOrganization: input.gitOrganization,
branch: input.branch,
directoryPath: input.directoryPath,
gitProvider: input.gitProvider,
isPublicRepo: input.isPublicRepo,
}).then((d) => d.createProjectRepository);
}
27 changes: 15 additions & 12 deletions ipaas/src/api/wip/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ const COMMIT_HISTORY_QUERY = `
}`;

const USER_REPOS_QUERY = `
query GetUserRepos {
userRepos {
query GetUserRepos($secretRef: String!) {
userRepos(secretRef: $secretRef) {
orgName
repositories { name }
}
}`;

const REPO_BRANCHES_QUERY = `
query GetRepoBranches($repositoryOrganization: String!, $repositoryName: String!, $isPublicRepo: Boolean!) {
repoBranchList(secretRef: "", repositoryOrganization: $repositoryOrganization, repositoryName: $repositoryName, isPublicRepo: $isPublicRepo) {
query GetRepoBranches($repositoryOrganization: String!, $repositoryName: String!, $isPublicRepo: Boolean!, $secretRef: String!) {
repoBranchList(secretRef: $secretRef, repositoryOrganization: $repositoryOrganization, repositoryName: $repositoryName, isPublicRepo: $isPublicRepo) {
name
isDefault
}
Expand Down Expand Up @@ -124,21 +124,21 @@ export async function fetchCommitHistory(componentId: string, branch: string): P
return gql<{ commitHistory: Commit[] }>(COMMIT_HISTORY_QUERY, { componentId, branch }).then((d) => d.commitHistory ?? []);
}

export async function fetchGitHubUserRepos(): Promise<UserRepo[]> {
return gql<{ userRepos: UserRepo[] }>(USER_REPOS_QUERY).then((d) => d.userRepos ?? []);
export async function fetchGitHubUserRepos(secretRef = ''): Promise<UserRepo[]> {
return gql<{ userRepos: UserRepo[] }>(USER_REPOS_QUERY, { secretRef }).then((d) => d.userRepos ?? []);
}

export async function fetchRepoBranches(repoOrg: string, repoName: string, isPublicRepo: boolean): Promise<RepoBranch[]> {
return gql<{ repoBranchList: RepoBranch[] }>(REPO_BRANCHES_QUERY, { repositoryOrganization: repoOrg, repositoryName: repoName, isPublicRepo }).then((d) => d.repoBranchList ?? []);
export async function fetchRepoBranches(repoOrg: string, repoName: string, isPublicRepo: boolean, secretRef = ''): Promise<RepoBranch[]> {
return gql<{ repoBranchList: RepoBranch[] }>(REPO_BRANCHES_QUERY, { repositoryOrganization: repoOrg, repositoryName: repoName, isPublicRepo, secretRef }).then((d) => d.repoBranchList ?? []);
}

export async function fetchRepoMetadata(org: string, repo: string, branch: string, subPath: string, isPublicRepo = false): Promise<RepoMetadata> {
export async function fetchRepoMetadata(org: string, repo: string, branch: string, subPath: string, isPublicRepo = false, secretRef = ''): Promise<RepoMetadata> {
return gql<{ repoMetadata: RepoMetadata }>(REPO_METADATA_QUERY, {
organizationName: org,
repoName: repo,
branch,
subPath: subPath.replace(/^\//, ''),
secretRef: '',
secretRef,
isPublicRepo,
}).then((d) => d.repoMetadata);
}
Expand Down Expand Up @@ -166,7 +166,10 @@ export async function obtainGithubToken(authorizationCode: string): Promise<{ su
return gql<{ obtainUserToken: { success: boolean; message: string } }>(OBTAIN_USER_TOKEN, { authorizationCode }).then((d) => d.obtainUserToken);
}

export async function fetchRepoContents(org: string, repo: string, branch: string, isPublicRepo = false): Promise<RepoTreeNode[]> {
const json = await withStsRetry(() => choreoClient.get<Record<string, unknown>>(`/component-mgt/1.0.0/repositories/${encodeURIComponent(org)}/${encodeURIComponent(repo)}/branches/${encodeURIComponent(branch)}/contents?isPublicRepo=${isPublicRepo}`));
export async function fetchRepoContents(org: string, repo: string, branch: string, isPublicRepo = false, secretRef = ''): Promise<RepoTreeNode[]> {
const secretParam = secretRef ? `&secretRef=${encodeURIComponent(secretRef)}` : '';
const json = await withStsRetry(() =>
choreoClient.get<Record<string, unknown>>(`/component-mgt/1.0.0/repositories/${encodeURIComponent(org)}/${encodeURIComponent(repo)}/branches/${encodeURIComponent(branch)}/contents?isPublicRepo=${isPublicRepo}${secretParam}`),
);
return (json?.data ?? json) as RepoTreeNode[];
}
Loading
Loading