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
1 change: 1 addition & 0 deletions site/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {
transform: {
react: {
runtime: "automatic",
importSource: "@emotion/react",
},
},
experimental: {
Expand Down
1 change: 1 addition & 0 deletions site/jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder as any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Polyfill for jsdom
global.Blob = Blob as any;
global.scrollTo = jest.fn();

// Polyfill the getRandomValues that is used on utils/random.ts
Object.defineProperty(global.self, "crypto", {
Expand Down
2 changes: 1 addition & 1 deletion site/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1104,7 +1104,7 @@ export const getTemplateExamples = async (
return response.data;
};

export const uploadTemplateFile = async (
export const uploadFile = async (
file: File,
): Promise<TypesGen.UploadResponse> => {
const response = await axios.post("/api/v2/files", file, {
Expand Down
7 changes: 7 additions & 0 deletions site/src/api/queries/files.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as API from "api/api";

export const uploadFile = () => {
return {
mutationFn: API.uploadFile,
};
};
8 changes: 8 additions & 0 deletions site/src/api/queries/templateVersions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as API from "api/api";

export const templateVersionLogs = (versionId: string) => {
return {
queryKey: ["templateVersion", versionId, "logs"],
queryFn: () => API.getTemplateVersionLogs(versionId),
};
};
73 changes: 55 additions & 18 deletions site/src/api/queries/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
type CreateTemplateVersionRequest,
type ProvisionerJobStatus,
type TemplateVersion,
CreateTemplateRequest,
ProvisionerJob,
} from "api/typesGenerated";
import { type QueryClient, type QueryOptions } from "react-query";
import { delay } from "utils/delay";
Expand Down Expand Up @@ -80,25 +82,10 @@ export const templateVersionVariables = (versionId: string) => {

export const createAndBuildTemplateVersion = (orgId: string) => {
return {
mutationFn: async (
request: CreateTemplateVersionRequest,
): Promise<string> => {
mutationFn: async (request: CreateTemplateVersionRequest) => {
const newVersion = await API.createTemplateVersion(orgId, request);

let data: TemplateVersion;
let jobStatus: ProvisionerJobStatus;
do {
await delay(1000);
data = await API.getTemplateVersion(newVersion.id);
jobStatus = data.job.status;

if (jobStatus === "succeeded") {
return newVersion.id;
}
} while (jobStatus === "pending" || jobStatus === "running");

// No longer pending/running, but didn't succeed
throw data.job.error;
await waitBuildToBeFinished(newVersion);
return newVersion;
},
};
};
Expand Down Expand Up @@ -133,3 +120,53 @@ export const templateVersionExternalAuth = (versionId: string) => {
queryFn: () => API.getTemplateVersionExternalAuth(versionId),
};
};

export const createTemplate = () => {
return {
mutationFn: createTemplateFn,
};
};

const createTemplateFn = async (options: {
organizationId: string;
version: CreateTemplateVersionRequest;
template: Omit<CreateTemplateRequest, "template_version_id">;
}) => {
const version = await API.createTemplateVersion(
options.organizationId,
options.version,
);
await waitBuildToBeFinished(version);
return API.createTemplate(options.organizationId, {
...options.template,
template_version_id: version.id,
});
};

const waitBuildToBeFinished = async (version: TemplateVersion) => {
let data: TemplateVersion;
let jobStatus: ProvisionerJobStatus;
do {
await delay(1000);
data = await API.getTemplateVersion(version.id);
jobStatus = data.job.status;

if (jobStatus === "succeeded") {
return version.id;
}
} while (jobStatus === "pending" || jobStatus === "running");

// No longer pending/running, but didn't succeed
throw new JobError(data.job, version);
};

export class JobError extends Error {
public job: ProvisionerJob;
public version: TemplateVersion;

constructor(job: ProvisionerJob, version: TemplateVersion) {
super(job.error);
this.job = job;
this.version = version;
}
}
Comment on lines +163 to +172
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have somewhere more general we can put these sorts of errors? not crazy about this being tucked away in queries/

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't but I'm open to it if you have any place or organization in mind.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe util/errors or something? I don’t tend to like util/ folders, but it’d be slightly more reusable there until we think of somewhere better

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... Idk but I feel it is kinda of far from where it is used since it is only used there - for now and probably it will be the only place where it makes sense IMO.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
MockTemplate,
MockTemplateExample,
MockTemplateVersionVariable1,
MockTemplateVersionVariable2,
Expand All @@ -21,16 +22,26 @@ const meta: Meta<typeof CreateTemplateForm> = {
export default meta;
type Story = StoryObj<typeof CreateTemplateForm>;

export const Initial: Story = {};
export const Upload: Story = {
args: {
upload: {
isUploading: false,
onRemove: () => {},
onUpload: () => {},
file: undefined,
},
},
};

export const WithStarterTemplate: Story = {
export const StarterTemplate: Story = {
args: {
starterTemplate: MockTemplateExample,
},
};

export const WithVariables: Story = {
export const DuplicateTemplateWithVariables: Story = {
args: {
copiedTemplate: MockTemplate,
variables: [
MockTemplateVersionVariable1,
MockTemplateVersionVariable2,
Expand All @@ -43,6 +54,7 @@ export const WithVariables: Story = {

export const WithJobError: Story = {
args: {
copiedTemplate: MockTemplate,
jobError:
"template import provision for start: recv import provision: plan terraform: terraform plan: exit status 1",
logs: [
Expand Down
Loading