Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Commit

Permalink
Merge pull request #144 from contember/content-migrations
Browse files Browse the repository at this point in the history
feat: add content migrations, restructurize migrations
  • Loading branch information
matej21 authored Jan 2, 2024
2 parents 0557e41 + 200f2f9 commit e05d861
Show file tree
Hide file tree
Showing 17 changed files with 527 additions and 315 deletions.
2 changes: 1 addition & 1 deletion docs/guides/acl-definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export class Comment {
As you can see, you can traverse through relations. Our definition says, that `moderator` can update fields `hiddenAt` and `content` of any `Comment` of an `Article` in a `Category` defined in `categoryId` variable.

:::note migrations
Don't forget to [create a migration](/reference/engine/schema/migrations.md) to apply changes:
Don't forget to [create a migration](/reference/engine/migrations/basics.md) to apply changes:
```bash
npm run contember migrations:diff my-blog setup-acl
```
Expand Down
4 changes: 2 additions & 2 deletions docs/intro/actions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Before this can work, though, you'll need to apply the changes using migrations.
npm run contember migrations:diff "my-first-action"
```

(Learn more about [schema migrations](/reference/engine/schema/migrations.md))
(Learn more about [migrations](/reference/engine/migrations/overview.md))

That's all there is to the Contember setup. To test this locally, refer to our [guide to Actions](/reference/engine/actions/overview). If you're using Contember Cloud, you'll need to enable Actions for your project in the interface.

Expand Down Expand Up @@ -69,4 +69,4 @@ The next step is to use this payload for your specific needs. In our case, we wa
<DocsCard header="Easy integrations with Actions and Superface AI" href="/guides/superface">
<p>Quick tutorial on how to quickly use Action with Superface AI.</p>
</DocsCard>
</DocsCards>
</DocsCards>
20 changes: 10 additions & 10 deletions docs/intro/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ title: Glossary

## Advanced

| Term | Definition |
| ----------------------- | ----------- |
| Workspace | Your (git) repository with one or more Contember projects. |
| [Content API](/reference/engine/content/overview.md) | This is the primary GraphQL API for your project, which is automatically generated from your schema definition. |
| System API | This is a supplementary API for your project. It's primarily used to manage schema migrations. You need it only in really advanced usecases. |
| [Tenant API](/reference/engine/tenant/overview.md) | This API allows you to manage users, API keys, and project memberships on an instance. |
| [Project Schema](/reference/engine/schema/overview.md) | This is the definition of your model, ACL rules, and input validation rules. |
| [Project Schema Migrations](/reference/engine/schema/migrations.md) | These are chronologically sorted, immutable JSON files that contain all schema changes. They serve as the source of truth for a schema. |
| Event | Every operation performed on your data is stored in an event log. This log can be utilized to track history. |
| Superadmin | This is a special user role within Contember. The Superadmin has the highest level of system access and control. |
| Term | Definition |
|----------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|
| Workspace | Your (git) repository with one or more Contember projects. |
| [Content API](/reference/engine/content/overview.md) | This is the primary GraphQL API for your project, which is automatically generated from your schema definition. |
| System API | This is a supplementary API for your project. It's primarily used to manage schema migrations. You need it only in really advanced usecases. |
| [Tenant API](/reference/engine/tenant/overview.md) | This API allows you to manage users, API keys, and project memberships on an instance. |
| [Project Schema](/reference/engine/schema/overview.md) | This is the definition of your model, ACL rules, and input validation rules. |
| [Project Migrations](/reference/engine/migrations/overview.md) | These are chronologically sorted, files that contain all schema or content changes. They serve as the source of truth for a schema. |
| Event | Every operation performed on your data is stored in an event log. This log can be utilized to track history. |
| Superadmin | This is a special user role within Contember. The Superadmin has the highest level of system access and control. |

<!--
ADD MODEL SCHEMA, INPUT VALIDATION RULES
Expand Down
2 changes: 1 addition & 1 deletion docs/intro/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Meet Contember AI Studio. Describe your ideal backend and AI and Contember will
| **Actions for data changes** (new in Engine v1.3) | Automate workflows, integrate with external systems, and enhance performance with Actions. |
| **Extendable with your React.js components** | Beyond out-of-the-box React components, Contember Interface lets you use React's full power to customise your applications. |
| **[Built-in authentication and authorization](/reference/engine/tenant/overview.md)** | Skip integrating third-party auth solutions and spend more time developing. |
| **[Automatic database migrations](/reference/engine/schema/migrations.md)** | Database schema changes are handled smoothly, reducing update risks. |
| **[Automatic database migrations](/reference/engine/migrations/overview.md)** | Database schema changes are handled smoothly, reducing update risks. |
| **Well-structured PostgreSQL database** | Focus on development, not database setup. We ensure that your data is organized and efficient, making it easier to manage and maintain. |
| **Everything is code** | Manage and deploy your entire application with version control systems like Git, simplifying multi-environment setups. |
| **Multi-language, translatable** | Build global-ready apps with ease thanks to multi-language support. |
Expand Down
2 changes: 1 addition & 1 deletion docs/intro/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ After defining your data model, you need to generate and execute a migration for

:::note What are migrations

Migrations are a way of version controlling your database schema. They provide a systematic approach to evolve your database schema over time, instead of making ad-hoc changes. This makes it easier to coordinate changes to the schema across a development team, especially when multiple developers are working on the same project and need to keep their local databases in sync. [Migrations in detail →](/reference/engine/schema/migrations)
Migrations are a way of version controlling your database schema. They provide a systematic approach to evolve your database schema over time, instead of making ad-hoc changes. This makes it easier to coordinate changes to the schema across a development team, especially when multiple developers are working on the same project and need to keep their local databases in sync. [Migrations in detail →](/reference/engine/migrations/overview.md)

:::

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ for example `npm run contember migr:exe`, which runs `migrations:execute` comman

### migrations:diff

See [migrations chapter](/reference/engine/schema/migrations.md).
See [migrations chapter](/reference/engine/migrations/overview.md).
2 changes: 1 addition & 1 deletion docs/reference/engine/actions/definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: Actions definition
This section of the documentation will guide you through the syntax and definition of Actions, facilitating their optimal utilization within your applications.

:::note
Keep in mind, whenever you add or modify Actions in Contember, it's essential to create and apply schema migrations. This ensures your changes are correctly integrated. You can learn more about [schema migrations](../schema/migrations.md).
Keep in mind, whenever you add or modify Actions in Contember, it's essential to create and apply schema migrations. This ensures your changes are correctly integrated. You can learn more about [migrations](../migrations/overview.md).
:::

## Defining a Watch Action
Expand Down
62 changes: 62 additions & 0 deletions docs/reference/engine/migrations/advanced/development-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: Commands for development
---

During local development, there may be a need to bypass certain checks, even if the migration has already been executed locally. This section details several commands that provide flexibility and control over your local migration process.

Please be aware that these commands are available exclusively on your local Contember instance and are not meant for production environments.

### Amending a Migration

While developing a new feature, you might find yourself needing to adjust an already created and applied schema migration. Instead of creating an entirely new diff, you can utilize the `migrations:amend` command. This command allows you to update the most recent migration both on disk and in your local Contember instance. If you revert the schema changes and run `migrations:amend`, the command effectively removes the migration.

#### Example: Amending Latest Migration

```bash
npm run contember migrations:amend
```

#### Example: Amending Specific Migration

You can target a specific migration to amend by providing an additional argument, as shown below:

```bash
npm run contember migrations:amend 2022-01-17-101806-test
```

:::note
If the migration has already been run by someone else or it's been deployed, it won't be possible to execute the amended migration.
:::

### Rebasing a Migration with `migrations:rebase`

Before merging a branch with a new migration, you might find that a new migration has been added upstream. The `migrations:rebase` command assists in resolving this by renaming the migrations both on disk and in your local Contember instance. Simply pass the names of the migrations you need to merge.

#### Example

```bash
npm run contember migrations:rebase 2022-01-17-101806-test
```

### Force Execution of Out-of-Order Migrations

When you pull code from upstream, there may be a new migration that precedes your local migrations. To bypass this, you can run the `migrations:execute` command with the `--force` flag.

#### Example: Force Executing

```bash
npm run contember migrations:execute --force
```

### <span className="version">Engine 1.3+</span> Executing Migrations Until a Specific Point with `--until`

In your development process, you might need to run a series of migrations up to a certain point. The `migrations:execute` command now allows you to use the `--until` flag for this purpose. This option executes all migrations up to and including the specified migration.

#### Example: Executing Until a Specific Migration

```bash
npm run contember migrations:execute --until 2022-01-17-101806-test
```



56 changes: 56 additions & 0 deletions docs/reference/engine/migrations/advanced/skipping-validations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: Skipping validation errors
---

## <span className="version">Engine 1.2+</span> Skipping validation errors

The `skippedErrors` feature in Contember allows users to specify a list of errors that should be ignored during validation of a migration. This can be useful in cases where a migration became invalid due to improvements and new checks in validator, but cannot be changed, because it is already applied.

To skip errors, open a migration file producing errors and add `skippedErrors` field. It is an array of objects, each of which contains a code and a path field. The code field specifies the error code, and the path field specifies the path to the element in the migration that caused the error. Path field is optional.

It is important to note that only individual migrations can have skipped errors, and the final migrated state must be valid. This means that any errors that are skipped in one migration must be fixed in a later migration in order for the migration process to be successful.

#### Example:

```json5
{
"skippedErrors": [
{
"code": "ACL_INVALID_CONDITION",
"path": "roles.reader.entities.ContentReference.predicates.test"
}
],
"formatVersion": 3,
"modifications": [
// Modifications here...
]
}
```

In this example, the `ACL_INVALID_CONDITION` error will be ignored for the test predicate in the ContentReference entity for the reader role.

### <span className="version">Engine 1.3+</span> `skipUntil`

In each error object, you can specify a `skipUntil` allowing to skip given validation until a specificed migration. This feature is useful when more migrations becomes invalid due to changes in the validator or data structure.

Example:

```json5
{
"skippedErrors": [
{
"code": "ACL_INVALID_CONDITION",
"path": "roles.reader.entities.ContentReference.predicates.test",
/* highlight-start */
"skipUntil": "2023-07-01-101530-abcd"
/* highlight-end */
}
],
"formatVersion": 3,
"modifications": [
// Modifications here...
]
}
```

In the above example, the "ACL_INVALID_CONDITION" error is ignored for a specific predicate in the ContentReference entity for the reader role. Additionally, subsequent validations will be skipped until the migration `2023-07-01-101530-abcd`.
112 changes: 112 additions & 0 deletions docs/reference/engine/migrations/advanced/writing-schema-migrations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: Writing or fixing migrations manually
---

Typically, you won't need to write migrations from scratch, but there may be occasions when you need to fine-tune or rectify a generated migration. When you open a generated `.json` migration file, you'll find a list of "modifications" that describe the changes made to your database schema. In such cases, you can manually adjust these modifications to tailor your migrations to specific requirements. Below are the available manual adjustments you can make to migrations.

### `fillValue` and `copyValue` support

In Contember, migrations can be manually adjusted or fixed when needed. When working with migrations, you may encounter two modifications, `createColumn` and `updateColumnDefinition`, which now support the `fillValue` and `copyValue` features. These options allow you to provide values during the migration process for added columns or modified columns that have been changed to disallow null values.

#### `createColumn` modification and `copyValue`/`fillValue`

The `createColumn` modification enables the addition of a new column to an entity. When creating a column that does not allow null values, you can utilize the following options:

- **fillValue**: Specifies a value that will be used to fill the column during the migration run. This value is distinct from the default value used at runtime. If a new column with a default value is added, the default value will also be used as the fillValue in the generated JSON migration.

- **copyValue**: Indicates the name of another column from which the value will be copied to the newly created column.

**Example:**

```json5
{
"modification": "createColumn",
"entityName": "Article",
"field": {
"name": "isPublished",
"columnName": "is_published",
"columnType": "boolean",
"nullable": false,
"type": "Bool"
},
/* highlight-start */
"fillValue": false
/* highlight-end */
}
```

#### <span className="version">Engine 1.3+</span> `updateColumnDefinition` modification and `copyValue`/`fillValue`

The `updateColumnDefinition` modification allows you to modify the definition of an existing column within an entity. When changing a column to disallow null values, you can make use of the following options:

- **fillValue**: Specifies a value that will be used to fill the column during the migration run. This option proves useful in populating the modified column with meaningful data when the nullability constraint is enforced.

- **copyValue**: Indicates the name of another column from which the value will be copied to the modified column.

**Example:**

```json5
{
"modification": "updateColumnDefinition",
"entityName": "Article",
"fieldName": "isPublished",
"definition": {
"columnType": "boolean",
"nullable": false,
"type": "Bool"
},
/* highlight-start */
"copyValue": "existingColumn"
/* highlight-end */
}
```

In this example, the value from an existing column named "existingColumn" will be copied to the modified column "isPublished" during the migration run.

### Renaming Entities

In Contember, renaming an entity involves creating a migration that drops the old entity and creates a new one. However, with the `updateEntityName` modification, you can instruct Contember to simply rename an existing entity without recreating it.

**Arguments:**

- **entityName**: The current name of the entity.
- **newEntityName**: The desired new name for the entity.
- **tableName**: You can optionally also change the name of the database table.

**Example:**

```json
{
"modification": "updateEntityName",
"entityName": "OldEntity",
"newEntityName": "NewEntity",
"tableName": "new_entity"
}
```

In this example, the entity named "OldEntity" will be renamed to "NewEntity" using the `updateEntityName` modification. Also, the table in database will be renamed to `new_entity`

### Renaming Fields

Similar to the `updateEntityName` modification, the `updateFieldName` modification allows you to rename a field within an entity.

**Arguments:**

- **entityName**: The name of the entity containing the field.
- **fieldName**: The current name of the field.
- **newFieldName**: The desired new name for the field.
- **columnName**: You can optionally change the name of the field in a database.

**Example:**

```json5
{
"modification": "updateFieldName",
"entityName": "Entity",
"fieldName": "oldField",
"newFieldName": "newField",
"columnName": "new_field"
}
```

In this example, the field named "OldField" within the entity "Entity" will be renamed to "NewField" using the `updateFieldName` modification.
55 changes: 55 additions & 0 deletions docs/reference/engine/migrations/basics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: Migrations workflow
---

### Creating a diff using `migrations:diff`

After you update your schema, you need to create a migration for your change, otherwise Contember won't see it.

There is a command to rescue you:

```bash
npm run contember migrations:diff <migration name>
```

#### Example: creating a diff

```bash
npm run contember migrations:diff add-categories
```

:::note
Name of a migration can only contain alphanumeric letters and a dash
:::

Contember will show you individual migration steps and ask you for confirmation.

You should check the steps with caution, because Contember cannot detect some changes correctly and it may result in a loss of your data. For example when you rename a field it drops the field and creates a new one.

If you have chosen to execute migration, you are done for now. If you haven't, you can check created `.json` file and [modify migration](./advanced/writing-schema-migrations.md) file manually describing the change more precisely.

### Explaining a migration using `migrations:describe`

You can again verify individual migration steps using `migrations:describe`. You can use `--sql-only` and `--no-sql` to alter output of the command.

#### Example: explaining migrations steps

```bash
npm run contember migrations:describe
```

### Executing migrations using `migrations:execute`

If you've pulled new migrations from upstream, or you want to execute a migration, you've created, you can apply all pending migrations using `migrations:execute`

#### Example: executing migrations

```bash
npm run contember migrations:execute
```

All the changes will be applied to both Contember schema and PostgreSQL database.

:::note
To execute migrations, you need [appropriate permissions](../schema/acl.md#migrations).
:::
Loading

0 comments on commit e05d861

Please sign in to comment.