Skip to content

AtidaTech/contentful-cli-migrations

Repository files navigation

License: MIT npm GitHub code size in bytes Downloads Forks Bun.sh

Contentful CLI Migrations

Contentful CLI Migrations is a JavaScript open-source library for automating Contentful migrations. It provides a convenient way to manage and apply migrations to your Contentful space using the command line.

Note: This is NOT the official Contentful Migration tool, but it's based on it. That can be found on GitHub πŸ”— or NpmJS πŸ”—

Sponsored by Atida Atida


✨ Features Β· πŸ’‘ Installation Β· πŸ“Ÿ Example Β· 🎹 Usage Β· 🐦 Write Migrations Β· πŸ“… ToDo Β· πŸ‘Ύ Contributors Β· 🎩 Acknowledgments Β· πŸ“š Collection Β· πŸ“„ License


✨ Features

  • Automated Migrations: Easily define and execute migrations to apply changes to your Contentful space.
  • Command Line Interface: Use a command-line interface to run migrations and manage the migration process.
  • Configuration: Define migration settings and options using a configuration file or command-line arguments.
  • Environment Integration: Seamlessly integrate migrations into your development and deployment workflow.
  • Version Control: Track and manage migrations using version control systems like Git.
  • Extensible: Customize and extend the migration functionality to suit your specific needs.

πŸ’‘ Installation

To use this helper library, you must have Node.js πŸ”— and npm πŸ”— installed.

To install it, simply run:

npm install contentful-cli-migrations --save

Or, if using yarn πŸ”—:

yarn add contentful-cli-migrations

Similarly, if you are using Bun πŸ”—, just run:

bun add contentful-cli-release

Requirements

  • node >= 18.0.0
  • npm >= 9.5.0
  • contentful-management >= 7.50.0
  • contentful-migration ^4.9.4
  • contentful-lib-helpers >= 0.3.3

Set-up

  1. Create a migrations/scripts/ directory in your project. This directory will contain your migration scripts.

  2. Define your migration scripts inside the migrations/scripts/ directory. Each migration script should be as follows:

    • Be a separate file with a specific naming convention, such as 0001-migration.cjs, 0002-migration.cjs, and so on.
    • The migration file names should contain a progressive number and a dash (-). In this way the script can intercept them.
    • We recommend using a certain amount of leading zeros to keep the migration in order inside the folder (that's why is 0001- and not 1-).
    • The folder should not contain any migration with a duplicated number (0002 and 02 will be considered duplicated).
    • Migration file's extension should be .js or .cjs depending on the use of "type": "module" in your package.json.
  3. In Contentful, you will need what we call a 'Counter' entry. It means that you will need to create an entry and assign one of its field to register the latest migration that has run successfully.

    • You will need to take note of the entry-id;
    • Then the field id. We recommend a content-type with very few fields.
    • And finally the locale of that field. If unsure, you should set it up as the default Locale, usually en-US or en-GB.

    Note: the entry can stay in 'draft' status, since it doesn't need to be published to be used.

  4. Set up your .env/.env.local configuration file to specify the required environment and migration settings. The configuration options include:

    • CMS_MANAGEMENT_TOKEN: The Contentful CMA token for accessing your Contentful space.
    • CMS_SPACE_ID: The ID of your Contentful space.
    • CMS_MIGRATIONS_DIR: The path to the migrations directory in your project.
    • CMS_MIGRATIONS_COUNTER_ID: The ID of the entry used to store the migration counter.
    • CMS_MIGRATIONS_COUNTER_FIELD: The ID of the field in the counter entry that stores the actual migration counter.
    • CMS_MIGRATIONS_COUNTER_LOCALE: The locale used to retrieve the migration counter from the field.

    You can define these options in a configuration file (e.g., .env) or pass them as command-line arguments when running the migrations.

When you start your project with contentful you usually start with an empty master environment. We have few advices on how to keep the migrations as clean as possible for different environments:

  • Set-up in your environment your default locale (ie: en-US) and eventually additional locales.
  • If possible, duplicate immediately the empty master environment as a new environment (ie: empty-DO-NOT-DELETE). This will ensure a clean environment where you could run a Contentful import or the migrations.
  • After that, create a content-type of type key-value for the Counter Entry. Or run the script with --initialise to set up the counter content-type and entry for you.
  • Once the Counter entry is created in the master environment, take note of the entry-id, field-id and locale. When duplicating master for your dev or staging environments, these values will remain the same (so you won't have to get confused with different values for different environments).
  • Ideally you should start creating all the Content-types using only migration scripts. Together with the empty environment, this will ensure the possibility to have a clean history of your Content-types.

πŸ“Ÿ Example

Once everything is set up, running migrations is actually pretty simple

npx contentful-cli-migrations --to "<environment-id>"

The --to (or --environment-id) is the only mandatory command line option. And it tells the environment to apply the migrations 'to'.

Since the management token would give you access to all environments, there is no default environment value in the .env file, forcing you to specify the target environment for 'safety' reasons (surely you don't want to run them on master accidentally).

🎹 Usage

This script can be used from the command line and accepts various arguments for customization:

  • --to or --environment-id [MANDATORY]: The environment id to which migrations will be executed.
  • --space-id: The Contentful space id.
  • --management-token or --mt: The Contentful Management Token.
  • --migrations-dir: To specify a custom directory for the migrations (default is sub-directory CMS_MIGRATIONS_DIR or migrations/scripts in your project root). The script will exit if this custom folder doesn't exist.
  • --initialise: This might be needed the first time to 'override' trying to read a Content-type and an Entry that don't exist yet. If you already have your environment set up, you can just create a counter entry of one of your existing Content-types, and skip this option.
  • --counter-id: The ID of the entry used to store the migration counter.
  • --counter-field: The ID of the field in the counter entry that stores the actual migration counter. Example: title.
  • --counter-locale: The locale used to retrieve the migration counter from the field. Default: en-US
  • --force-yes: The script runs a migration at a time, asking you to confirm it manually (Y/N). In a CD/CI pipeline, you will need to set up --force-yes so that all migrations will run without any request for interaction.

🐦 Write migrations

There are some guidelines and some few tricks that can be implemented when writing a Contentful migration. For more info, look at the separate documentation on How to Write Migrations.

πŸ“… Todo

  • Add Rollback migrations support.
  • Add Migration Diff and automatic generator.
  • Add better logging (+ colors).
  • Add tests.

πŸ‘Ύ Contributors

Fabrizio Ciacchi
@fciacchi

Victor Hugo Aizpuruo
@psyvic

Aldo FernΓ‘ndez
@aalduz

Stefan Stoev
@leslyto


Contributions

Feel free to open issues or pull requests in our GitHub Repository if you have suggestions or improvements to propose.

🎩 Acknowledgements

I would like to express my gratitude to the following parties:

  • Atida πŸ”—, the company that has allowed these scripts to be open sourced. Atida is an e-commerce platform that sells beauty and medical products. Their support for open source is greatly appreciated. A special thank to
  • Shaya Pourmirza Shaya Pourmirza that has been a great promoter and supporter of this initiative inside the company.
  • Contentful πŸ”—, for creating their excellent content management platform and the JavaScript CMA SDK that this
  • library is built on. Without their work, this project would not be possible.

Thank you to everyone involved!

πŸ“š Other Scripts in the same collection

We produce a bunch of interesting packages for Contentful. You might want to check them out:

  • Contentful Lib Helpers (GitHub and NpmJS): Utility Library for Contentful Management API.
  • Contentful CLI Export (GitHub and NpmJS): Simplifies backup of your Contentful Environment.
  • Contentful CLI Migrations (GitHub and NpmJS): Tool to automate and scale Contentful Migrations.
  • Contentful CLI Release (GitHub and NpmJS): Release utilities to deploy Contentful in a CI/CD.

πŸ“„ License

This project is licensed under the MIT License