Skip to content
Merged
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
18 changes: 4 additions & 14 deletions sdk/openapi/cloud.openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -194,19 +194,7 @@ components:
region: { type: string }
environmentId: { type: string }
serviceId: { type: [string, "null"] }
NewUploadService:
type: object
required: [name, appName, source]
properties:
name: { type: string }
appName: { type: string }
source:
type: object
required: [type]
properties:
type: { type: string, const: upload }
port: { type: [integer, "null"] }
isPublic: { type: boolean }
NewService: { $ref: 'services.yaml#/schemas/NewService' }
CreatedService:
type: object
required: [serviceId, name, appName]
Expand Down Expand Up @@ -239,6 +227,7 @@ components:
required: [serviceId, scaling, volumeLimits]
properties:
serviceId: { type: string }
source: { $ref: 'services.yaml#/schemas/ServiceSettingsSource' }
scaling:
type: object
required: [bounds, replicaLimit, pricing]
Expand Down Expand Up @@ -353,7 +342,7 @@ paths:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/NewUploadService' }
schema: { $ref: '#/components/schemas/NewService' }
responses:
'200':
content:
Expand Down Expand Up @@ -387,6 +376,7 @@ paths:
default: { $ref: '#/components/responses/Error' }
/api/cloud/services/{serviceId}/port: { $ref: 'services.yaml#/paths/port' }
/api/cloud/services/{serviceId}/network: { $ref: 'services.yaml#/paths/network' }
/api/cloud/services/{serviceId}/source-dockerfile: { $ref: 'services.yaml#/paths/sourceDockerfile' }
/api/cloud/services/{serviceId}/variables/references: { $ref: 'services.yaml#/paths/variableReferences' }
/api/cloud/services/{serviceId}/source-deployments:
post:
Expand Down
89 changes: 89 additions & 0 deletions sdk/openapi/services.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,55 @@
schemas:
NewService:
description: |
A service to create in an environment. Its source says where its deployments come
from: an upload each `ajs cloud deploy` carries, or a repository AntelopeJS Cloud
builds at each push.
type: object
required: [name, appName, source]
properties:
name: { type: string }
appName: { type: string }
source:
oneOf:
- $ref: '#/schemas/UploadSource'
- $ref: '#/schemas/RepositorySource'
port: { type: [integer, "null"] }
isPublic: { type: boolean }
UploadSource:
type: object
required: [type]
properties:
type: { type: string, const: upload }
RepositorySource:
description: |
A GitHub repository the workspace's GitHub installation grants. Two services of one
repository differ by their Dockerfile: an API built by the AntelopeJS recipe next to
a dashboard built by `frontend.Dockerfile`.
type: object
required: [type, repository]
properties:
type: { type: string, const: repository }
repository: { type: string, description: "The repository, as `owner/name`." }
branch:
description: The branch this service builds; null or absent follows its environment's branch.
type: [string, "null"]
dockerfilePath: { $ref: '#/schemas/DockerfilePath' }
DockerfilePath:
description: |
Path, inside the repository, of the Dockerfile that builds the service, such as
`frontend.Dockerfile` or `apps/web/Dockerfile`: plain segments of letters, digits,
`.`, `_` and `-`, separated by `/`. Null or absent: the root `Dockerfile` when the
repository has one, else a recipe.
type: [string, "null"]
maxLength: 255
ServiceSettingsSource:
description: Where the service's deployments come from.
type: object
required: [type]
properties:
type: { type: string, enum: [repository, image, upload, database] }
repository: { type: [string, "null"], description: "`owner/name`, for a repository source." }
dockerfilePath: { $ref: '#/schemas/DockerfilePath' }
paths:
port:
put:
Expand Down Expand Up @@ -124,3 +176,40 @@ paths:
application/json:
schema: { $ref: './cloud.openapi.yaml#/components/schemas/Error' }
default: { $ref: './cloud.openapi.yaml#/components/responses/Error' }
sourceDockerfile:
put:
operationId: setServiceDockerfile
description: |
Names the Dockerfile, inside its repository, that builds the service, or goes back
to the root `Dockerfile` or a recipe with null. The next build reads it; the
revisions already built keep their image. A build of a commit that holds no file at
that path fails with `cloud.errors.builds.dockerfile_not_found`.
security: [{ bearerAuth: [] }]
parameters:
- in: path
name: serviceId
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [path]
properties:
path: { $ref: '#/schemas/DockerfilePath' }
responses:
'200':
description: Done
'400':
description: '`cloud.errors.settings.invalid_dockerfile_path`: not a plain relative path inside the repository.'
content:
application/json:
schema: { $ref: './cloud.openapi.yaml#/components/schemas/Error' }
'409':
description: '`cloud.errors.settings.not_a_repository_source`: the service does not build a repository. `cloud.errors.settings.preview_read_only`: a preview mirrors its environment and is not edited.'
content:
application/json:
schema: { $ref: './cloud.openapi.yaml#/components/schemas/Error' }
default: { $ref: './cloud.openapi.yaml#/components/responses/Error' }
36 changes: 34 additions & 2 deletions sdk/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ export type EnvironmentVariable = components["schemas"]["EnvironmentVariable"];
export type EnvironmentVariableList =
components["schemas"]["EnvironmentVariableList"];
export type NewProject = components["schemas"]["NewProject"];
export type NewUploadService = components["schemas"]["NewUploadService"];
/** A service to create: one each `ajs cloud deploy` uploads, or one built from a repository. */
export type NewService = components["schemas"]["NewService"];
/** A service whose deployments each carry their own uploaded source. */
export type NewUploadService = NewService & { source: { type: "upload" } };
/** A service AntelopeJS Cloud builds from a repository at each push. */
export type NewRepositoryService = NewService & {
source: { type: "repository" };
};
export type VariableOrigin = components["schemas"]["VariableOrigin"];
export type VariableWrite = components["schemas"]["VariableWrite"];
export type WorkspaceProvisioning =
Expand Down Expand Up @@ -151,10 +158,17 @@ export class CloudApi {
return dataOf(result);
}

/**
* Creates a service in an environment. With a `repository` source it builds
* that repository at each push to the environment's branch, with the
* Dockerfile its `dockerfilePath` names when it has one: that is how a
* second service, such as a dashboard built by `frontend.Dockerfile`, is
* built from the repository of the first.
*/
async createService(
projectId: string,
environmentId: string,
body: NewUploadService,
body: NewService,
) {
const result = await this.client.POST(
"/api/cloud/projects/{projectId}/environments/{environmentId}/services",
Expand Down Expand Up @@ -296,6 +310,24 @@ export class CloudApi {
acceptedOf(result);
}

/**
* Names the Dockerfile, inside its repository, that builds the service, or
* goes back to the root `Dockerfile` or a recipe with `null`. The next
* build reads it. A path that is not a plain relative path is refused with
* `cloud.errors.settings.invalid_dockerfile_path`, a service that builds no
* repository with `cloud.errors.settings.not_a_repository_source`.
*/
async setServiceDockerfile(
serviceId: string,
path: string | null,
): Promise<void> {
const result = await this.client.PUT(
"/api/cloud/services/{serviceId}/source-dockerfile",
{ params: { path: { serviceId } }, body: { path }, parseAs: "text" },
);
acceptedOf(result);
}

/**
* Adds a variable to the service that follows a value another service of
* its environment publishes, such as the `MONGO_URL` of a MongoDB resource.
Expand Down
115 changes: 109 additions & 6 deletions sdk/src/generated/cloud-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,28 @@ export interface paths {
patch?: never;
trace?: never;
};
"/api/cloud/services/{serviceId}/source-dockerfile": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
/**
* @description Names the Dockerfile, inside its repository, that builds the service, or goes back
* to the root `Dockerfile` or a recipe with null. The next build reads it; the
* revisions already built keep their image. A build of a commit that holds no file at
* that path fails with `cloud.errors.builds.dockerfile_not_found`.
*/
put: operations["setServiceDockerfile"];
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/api/cloud/services/{serviceId}/variables/references": {
parameters: {
query?: never;
Expand Down Expand Up @@ -715,13 +737,15 @@ export interface components {
environmentId: string;
serviceId?: string | null;
};
NewUploadService: {
/**
* @description A service to create in an environment. Its source says where its deployments come
* from: an upload each `ajs cloud deploy` carries, or a repository AntelopeJS Cloud
* builds at each push.
*/
NewService: {
name: string;
appName: string;
source: {
/** @constant */
type: "upload";
};
source: components["schemas"]["UploadSource"] | components["schemas"]["RepositorySource"];
port?: number | null;
isPublic?: boolean;
};
Expand All @@ -746,6 +770,7 @@ export interface components {
};
ServiceSettings: {
serviceId: string;
source?: components["schemas"]["ServiceSettingsSource"];
scaling: {
bounds: components["schemas"]["ServiceBounds"];
replicaLimit: number;
Expand Down Expand Up @@ -921,6 +946,31 @@ export interface components {
environmentId: string;
services: components["schemas"]["ServiceHealth"][];
};
UploadSource: {
/** @constant */
type: "upload";
};
/**
* @description Path, inside the repository, of the Dockerfile that builds the service, such as
* `frontend.Dockerfile` or `apps/web/Dockerfile`: plain segments of letters, digits,
* `.`, `_` and `-`, separated by `/`. Null or absent: the root `Dockerfile` when the
* repository has one, else a recipe.
*/
DockerfilePath: string | null;
/**
* @description A GitHub repository the workspace's GitHub installation grants. Two services of one
* repository differ by their Dockerfile: an API built by the AntelopeJS recipe next to
* a dashboard built by `frontend.Dockerfile`.
*/
RepositorySource: {
/** @constant */
type: "repository";
/** @description The repository, as `owner/name`. */
repository: string;
/** @description The branch this service builds; null or absent follows its environment's branch. */
branch?: string | null;
dockerfilePath?: components["schemas"]["DockerfilePath"];
};
/** @description A monthly amount in the plan's currency. A plan that rates nothing a database holds includes it, with no amount to show. */
MonthlyCost: {
/** @constant */
Expand Down Expand Up @@ -1050,6 +1100,14 @@ export interface components {
/** @description The plan that remains once the databases are created. */
plan: components["schemas"]["ResourcePlan"];
};
/** @description Where the service's deployments come from. */
ServiceSettingsSource: {
/** @enum {string} */
type: "repository" | "image" | "upload" | "database";
/** @description `owner/name`, for a repository source. */
repository?: string | null;
dockerfilePath?: components["schemas"]["DockerfilePath"];
};
/** @description What a built revision was built from. */
RevisionBuild: {
/** @description The branch built; null for a source the CLI uploaded. */
Expand Down Expand Up @@ -1523,7 +1581,7 @@ export interface operations {
};
requestBody: {
content: {
"application/json": components["schemas"]["NewUploadService"];
"application/json": components["schemas"]["NewService"];
};
};
responses: {
Expand Down Expand Up @@ -1796,6 +1854,51 @@ export interface operations {
default: components["responses"]["Error"];
};
};
setServiceDockerfile: {
parameters: {
query?: never;
header?: never;
path: {
serviceId: string;
};
cookie?: never;
};
requestBody: {
content: {
"application/json": {
path: components["schemas"]["DockerfilePath"];
};
};
};
responses: {
/** @description Done */
200: {
headers: {
[name: string]: unknown;
};
content?: never;
};
/** @description `cloud.errors.settings.invalid_dockerfile_path`: not a plain relative path inside the repository. */
400: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
/** @description `cloud.errors.settings.not_a_repository_source`: the service does not build a repository. `cloud.errors.settings.preview_read_only`: a preview mirrors its environment and is not edited. */
409: {
headers: {
[name: string]: unknown;
};
content: {
"application/json": components["schemas"]["Error"];
};
};
default: components["responses"]["Error"];
};
};
followPublishedValue: {
parameters: {
query?: never;
Expand Down
Loading
Loading