npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@unicefnz/contentful-migrator

v1.1.3

Published

Opinionated Contentful migration tooling

Downloads

9

Readme

Contentful Migrator

This package is an opinionated pipeline for managing your Contentful schema. Used in production at UNICEF New Zealand, we use this to extend infrastructure-as-code to our CMS.

Setup

See the /example/ folder for some example code on how to set up this tool (such as workflows and source code)

Creating tracking entry

In order to track which migrations have been applied to which migrations, this tool creates an entry to track each applied migration.

You'll need to add this by hand to start with.

  • ID: appliedMigration (or choose another and pass options.migrationTrackerEntryType)
  • Fields
    • name
      • Symbol
      • Required
    • migrationResult
      • Text
      • Not required
{
  "sys": {
    "id:": "appliedMigrations"
  },
  "name": "Z-Internal: Applied Migrations",
  "description": "*Automation only*\nTracks the state of the Content Model for automatic migrations",
  "displayField": "name",
  "fields": [
    {
      "id": "name",
      "name": "Migration Name",
      "type": "Symbol",
      "localized": false,
      "required": true,
      "validations": []
    },
    {
      "id": "migrationResult",
      "name": "Migration Result",
      "type": "Text", 
      "localized": false,
      "required": false,
      "validations": []
    }
  ]
}

Strategies

"Strategies" are used to select an environment and perform some behaviour based on which branch this runs on. For example, this may just mean selecting the master env when on the main branch, or creating an ad-hoc environment on a feature branch.

Using default strategy

The default strategy assumes you have two environments, master & test (names configurable).

The master environment is your production content and stable version of your schema. This corresponds to the main branch

The test environment contains dummy content used for testing & development. This separation allows you to snapshot test against this environment.

Additionally, this strategy will create ad-hoc feature environments corresponding to feature branches. The purpose of this is to allow (potentially broken) migrations to be run against an environment that can be recreated.

Example:

  migrate({
    // ...
    strategy: defaultStrategy({
      recreateFeatureEnvironments: true,
      testEnvironment: 'test'
    })
  });

Creating your own strategy

If the default strategy doesn't fit your workflow, you can use your own.

You'll need to pass an action to take as the strategy prop. This action gets some context, and may use this to perform some actions, eventually returning the environment to perform the migrations on.

interface ActionResult {
  env: Environment;
  onComplete?(): void;
}

type StrategyAction = (context: ActionContext) => Promise<ActionResult>;

Creating a migration

  1. Define your migration, creating a file with the next number in the sequence (eg, 09-example.ts)

  2. Using this boilerplate, create your migration

    See Migration DSL docs for more info about how to use the migration object

    import type Migration from 'contentful-migration';
        
    function runMigration(migration: Migration) {
      // Migration goes here
    }
        
    export = runMigration;
  3. Test your migration by committing it to a feature branch (eg feat/my-migration), and pushing it. This will create a new environment (feat_my-migration) in Contentful and apply any missing migrations. If you need to edit your migration, delete the new environment, and push your change. (If recreateFeatureEnvironments = true, this is done automatically.)

  4. Once ready, squash and merge your feature branch into develop and verify the test environment looks right

  5. If everything looks good, fast-forward main to update the master environment. Congrats! Your migration is live!

Configuration

migrate(options)

  • options.token - Access token for the Contentful Content Management API (CMA) Default: process.env.CONTENTFUL_ACCESS_TOKEN

  • options.spaceId- Space to apply migrations to. Default: process.env.CONTENTFUL_SPACE_ID

  • options.locale - Default locale (mainly used for migration tracking) Default: 'en-US'

  • Required options.migrationPath - Filesystem path to a directory containing your migration files. Example: path.resolve(__dirname, './migrations')

  • options.migrationTrackerEntryType - Entry Type used for tracking which migrations have been applied. Default: 'appliedMigration'

  • Required options.strategy - Configures environment strategy behavior.

defaultStrategy(options)

  • options.branchRef - Branch this is running on, determines which action to take. Default: process.env.GITHUB_REF

  • options.recreateFeatureEnvironments - Whether to automatically destroy and recreate existing feature environments. Speeds up testing a migration. Default: false

  • options.testEnvironment - Testing contentful environment, feature environments are copied from this. Default: test

  • options.productionBranch / options.developmentBranch / options.featureBranch - Matching logic for each type of branch.

    • string - branch === matcher
    • string[] - branch in matcher
    • function - matcher(branch)

How it works

This repo defines "migrations", similar to SQL migrations. Each migration gets applied on top of a base state, to keep changes to environments in sync and reproducible.

The tool uses the git branch name to determine which Contentful environment to apply changes to, and entries in the environment to track which migrations have been applied.

  1. Determine which git branch we are on. This is used to determine what strategy to use
  2. Use the corresponding strategy to determine which Contentful environment to act on, and perform other side effects (such as creating the environment)
  3. Determine which migrations need to be applied
  4. Apply the migrations sequentially
  5. Save a record of the migration being applied in the environment itself
  6. Profit

This pipeline is based on the following articles: