Create production, staging and development targets by default for new projects (#196)

This commit is contained in:
Kamil Kisiela 2022-06-28 16:41:24 +02:00 committed by GitHub
parent 9cee7420a7
commit ebddde55e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 103 additions and 41 deletions

View file

@ -104,9 +104,10 @@ export function createProject(input: CreateProjectInput, authToken: string) {
id
cleanId
}
createdTarget {
createdTargets {
id
cleanId
name
}
}
}

View file

@ -22,7 +22,7 @@ test('can publish persisted operations only with project:operations-store:write'
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with no rights
const noAccessTokenResult = await createToken(
@ -127,7 +127,7 @@ test('should skip on already persisted operations', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(

View file

@ -0,0 +1,45 @@
import { ProjectType } from '@app/gql/graphql';
import { createOrganization, createProject } from '../../../testkit/flow';
import { authenticate } from '../../../testkit/auth';
test('creating a project should result in creating the development, staging and production targets', async () => {
const { access_token } = await authenticate('main');
const orgResult = await createOrganization(
{
name: 'foo',
},
access_token
);
const org = orgResult.body.data!.createOrganization.ok!.createdOrganizationPayload.organization;
const projectResult = await createProject(
{
organization: org.cleanId,
type: ProjectType.Single,
name: 'foo',
},
access_token
);
const targets = projectResult.body.data!.createProject.ok!.createdTargets;
expect(targets).toHaveLength(3);
expect(targets).toContainEqual(
expect.objectContaining({
cleanId: 'development',
name: 'development',
})
);
expect(targets).toContainEqual(
expect.objectContaining({
cleanId: 'staging',
name: 'staging',
})
);
expect(targets).toContainEqual(
expect.objectContaining({
cleanId: 'production',
name: 'production',
})
);
});

View file

@ -34,7 +34,7 @@ test('can check a schema with target:registry:read access', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -145,7 +145,7 @@ test('should match indentation of previous description', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(

View file

@ -43,7 +43,7 @@ test('cannot publish a schema without target:registry:write access', async () =>
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{
@ -98,7 +98,7 @@ test('can publish a schema with target:registry:write access', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{
@ -175,7 +175,7 @@ test('base schema should not affect the output schema persisted in db', async ()
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -276,7 +276,7 @@ test('directives should not be removed (federation)', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -352,7 +352,7 @@ test('should allow to update the URL of a Federated service without changing the
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -443,7 +443,7 @@ test('should allow to update the URL of a Federated service while also changing
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -532,7 +532,7 @@ test('directives should not be removed (stitching)', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -608,7 +608,7 @@ test('directives should not be removed (single)', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -684,7 +684,7 @@ test('share publication of schema using redis', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -758,7 +758,7 @@ test("Two targets with the same commit id shouldn't return an error", async () =
owner_access_token
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const writeTokenResult = await createToken(
{
name: 'test',
@ -843,7 +843,7 @@ test('marking versions as valid', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{
@ -987,7 +987,7 @@ test('marking only the most recent version as valid result in an update of CDN',
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{
@ -1133,7 +1133,7 @@ test('CDN data can not be fetched with an invalid access token', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{
@ -1215,7 +1215,7 @@ test('CDN data can be fetched with an valid access token', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{

View file

@ -35,7 +35,7 @@ test('marking only the most recent version as valid result in an update of CDN',
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{

View file

@ -38,7 +38,7 @@ test('cannot set a scope on a token if user has no access to that scope', async
const member = joinResult.body.data!.joinOrganization.organization.me;
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Give access to tokens
await updateMemberAccess(

View file

@ -53,7 +53,7 @@ test('collect operation', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const settingsTokenResult = await createToken(
{
@ -216,7 +216,7 @@ test('normalize and collect operation without breaking its syntax', async () =>
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const settingsTokenResult = await createToken(
{
@ -393,7 +393,7 @@ test('number of produced and collected operations should match (no errors)', asy
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{
@ -491,7 +491,7 @@ test('check usage from two selected targets', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const staging = projectResult.body.data!.createProject.ok!.createdTarget;
const staging = projectResult.body.data!.createProject.ok!.createdTargets[0];
const productionTargetResult = await createTarget(
{
@ -685,7 +685,7 @@ test('number of produced and collected operations should match', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
const tokenResult = await createToken(
{

View file

@ -34,7 +34,7 @@ test('can publish and check a schema with target:registry:read access', async ()
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -94,7 +94,7 @@ test('service url should be available in supergraph', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -163,7 +163,7 @@ test('service url should be required in Federation', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -221,7 +221,7 @@ test('schema:check should notify user when registry is empty', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(
@ -267,7 +267,7 @@ test('schema:check should throw on corrupted schema', async () => {
);
const project = projectResult.body.data!.createProject.ok!.createdProject;
const target = projectResult.body.data!.createProject.ok!.createdTarget;
const target = projectResult.body.data!.createProject.ok!.createdTargets[0];
// Create a token with write rights
const writeTokenResult = await createToken(

View file

@ -48,7 +48,7 @@ export default gql`
type CreateProjectOk {
selector: ProjectSelector!
createdProject: Project!
createdTarget: Target!
createdTargets: [Target!]!
}
type CreateProjectInputErrors {

View file

@ -62,11 +62,26 @@ export const resolvers: ProjectModule.Resolvers & { ProjectType: any } = {
...input,
organization,
});
const target = await injector.get(TargetManager).createTarget({
name: 'experiment',
project: project.id,
organization,
});
const targetManager = injector.get(TargetManager);
const targets = await Promise.all([
targetManager.createTarget({
name: 'production',
project: project.id,
organization,
}),
targetManager.createTarget({
name: 'staging',
project: project.id,
organization,
}),
targetManager.createTarget({
name: 'development',
project: project.id,
organization,
}),
]);
return {
ok: {
@ -75,7 +90,7 @@ export const resolvers: ProjectModule.Resolvers & { ProjectType: any } = {
project: project.cleanId,
},
createdProject: project,
createdTarget: target,
createdTargets: targets,
},
};
},

View file

@ -19,7 +19,7 @@ const CreateProjectMutation = gql(/* GraphQL */ `
createdProject {
...ProjectFields
}
createdTarget {
createdTargets {
...TargetFields
}
}
@ -95,7 +95,8 @@ export const CreateProjectModal = ({
<Heading className="text-center">Create a project</Heading>
<p className="text-sm text-gray-500">
A project is built on top of <b>Targets</b>, which are just your environments. We will also create a default
stack named <b>experiment</b> for you (don't worry, you can change it later).
stacks named <b>production</b>, <b>staging</b> and <b>development</b> for you (don't worry, you can change it
later).
</p>
<div className="flex flex-col gap-4">

View file

@ -8,7 +8,7 @@ mutation createProject($input: CreateProjectInput!) {
createdProject {
...ProjectFields
}
createdTarget {
createdTargets {
...TargetFields
}
}