Skip to content

Commit

Permalink
ci: New Contentful schema deployment scripts (#386)
Browse files Browse the repository at this point in the history
* ci: Create environment clone for release script

* ci: Create the alias switch script for promotion and rollback

* Update create-new-env-version.ts

* Update switch-alias-for-release.ts

* Update resyncEditorInterface.ts

* Update create-new-env-version.ts

* Create create-schema-release.yml

* Create rollback-switch-master-alias-for-release.yml

* Create switch-master-alias-for-release.yml

* Rename actions

* Update switch-alias-for-release.ts

* Test this against a dummy alias first

* Add dispatch event
  • Loading branch information
killij authored Jan 25, 2024
1 parent 5e941aa commit dc37bec
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 18 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/create-schema-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Production Create Schema Release

on: workflow_dispatch

jobs:
create-schema-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
working-directory: ./Contentful-Schema/
run: |
npm ci
- name: Build scripts
working-directory: ./Contentful-Schema/
run: |
npx tsc
- name: Run script
env:
CONTENTFUL_MANAGEMENT_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }}
CPD_SPACE_ID: ${{ secrets.TF_VAR_CPD_SPACE_ID }}
working-directory: ./Contentful-Schema
run: |
node ./dist/scripts/schema-release-process/create-new-env-version.js -s pre-prod -t dummy
27 changes: 27 additions & 0 deletions .github/workflows/rollback-master-alias-to-previous-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Production rollback master alias to previous release

on: workflow_dispatch

jobs:
create-schema-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
working-directory: ./Contentful-Schema/
run: |
npm ci
- name: Build scripts
working-directory: ./Contentful-Schema/
run: |
npx tsc
- name: Run script
env:
CONTENTFUL_MANAGEMENT_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }}
CPD_SPACE_ID: ${{ secrets.TF_VAR_CPD_SPACE_ID }}
working-directory: ./Contentful-Schema
run: |
node ./dist/scripts/schema-release-process/switch-alias-for-release.js -a dummy -r
27 changes: 27 additions & 0 deletions .github/workflows/switch-master-alias-to-new-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Production switch master alias to new release

on: workflow_dispatch

jobs:
create-schema-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
working-directory: ./Contentful-Schema/
run: |
npm ci
- name: Build scripts
working-directory: ./Contentful-Schema/
run: |
npx tsc
- name: Run script
env:
CONTENTFUL_MANAGEMENT_TOKEN: ${{ secrets.CONTENTFUL_MANAGEMENT_TOKEN }}
CPD_SPACE_ID: ${{ secrets.TF_VAR_CPD_SPACE_ID }}
working-directory: ./Contentful-Schema
run: |
node ./dist/scripts/schema-release-process/switch-alias-for-release.js -a dummy
24 changes: 12 additions & 12 deletions Contentful-Schema/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Contentful-Schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"boxen": "^7.1.1",
"chalk": "^5.3.0",
"contentful-cli": "^3.1.14",
"contentful-management": "^11.5.1",
"contentful-management": "^11.13.1",
"inquirer": "^9.2.12",
"listr2": "^7.0.2",
"yargs": "^17.7.2"
Expand Down
11 changes: 6 additions & 5 deletions Contentful-Schema/src/scripts/resyncEditorInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ const ctx: MainContext = {
contentTypes: []
}

const options = {
concurrent: false,
ctx,
renderer: argv.o as string
}

const tasks = new Listr<MainContext>(
[
Expand Down Expand Up @@ -85,11 +90,7 @@ const tasks = new Listr<MainContext>(
}
}
],
{
concurrent: false,
ctx,
renderer: argv.o as string
}
options as unknown as any
)

try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import boxen from "boxen"
import yargs from "yargs"
import { hideBin } from "yargs/helpers"

import chalk from "chalk"
import contentful from 'contentful-management'

console.log(boxen(chalk.whiteBright("Clone an Alias target environment to a new version"), {padding: 1}));
const argv = await yargs(hideBin(process.argv))
.usage('Usage: $0 [options]')
.describe("s", "The environment to be cloned into a new version")
.alias("s", "source-environment")
.describe("t", "The target alias")
.alias("t", "target-alias")
.help(false)
.version(false)
.demandOption(["s", "t"])
.argv

const token = process.env.CONTENTFUL_MANAGEMENT_TOKEN as string
if (!token) throw new Error("No Contentful management API key specified, make sure you've set the CONTENTFUL_MANAGEMENT_ACCESS_TOKEN environment variable")

const spaceId = process.env.CPD_SPACE_ID as string
if (!spaceId) throw new Error("No space specified, make sure you've set the CPD_SPACE_ID environment variable")

const sourceEnvironmentName = argv.s as string
if (!sourceEnvironmentName) throw new Error("No alias specified")

const targetAliasId = argv.t as string

console.log("Creating Contentful client")
const client = contentful.createClient({ accessToken: token })

console.log(`Fetching space`)
const space = await client.getSpace(spaceId)

console.log(`Fetching list of all environments`)
const allEnvironments = await space.getEnvironments()

console.log(`Locating source environment ${chalk.yellowBright(sourceEnvironmentName)}`)
const environment = allEnvironments.items.find(e => e.name === sourceEnvironmentName)

if (!environment) {
throw new Error(`Source environment ${chalk.yellowBright(sourceEnvironmentName)} not found`)
}

console.log(`Fetching target alias ${chalk.yellowBright(targetAliasId)}`)
const targetAlias = await space.getEnvironmentAlias(targetAliasId)

console.log(`Fetching alias's target environment ${chalk.yellowBright(targetAlias.environment.sys.id)}`)
const currentEnvironment = allEnvironments.items.find(e => e.sys.id === targetAlias.environment.sys.id)

if (!currentEnvironment) {
throw new Error(`Alias's target environment ${chalk.yellowBright(targetAlias.environment.sys.id)} not found`)
}

console.log("Generating new environment name")
console.log(`Current Environment name is ${chalk.yellowBright(currentEnvironment.name)}`)
const tokens = environment.name.split("__")
if (tokens === undefined) {
throw new Error(`${chalk.redBright("Error:")} Environment ${chalk.yellowBright(environment.sys.id)} is not in the correct format`)
}

let version = tokens.length > 1 ? parseInt(tokens[1]) : 1
const newEnvName = `${currentEnvironment.name}__${version+1}`

console.log(`New environment name will be ${chalk.yellowBright(newEnvName)}`)

console.log(`Checking if environment ${chalk.yellowBright(newEnvName)} already exists`)
if (allEnvironments.items.find(e => e.name === newEnvName)) {
throw new Error(`Next release environment ${chalk.yellowBright(newEnvName)} already exists`)
}

console.log(`Cloning new environment ${chalk.yellowBright(newEnvName)} from ${chalk.yellowBright(environment.name)}`)
await space.createEnvironmentWithId(newEnvName, { name: newEnvName }, environment.name)

console.log("Done")
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import boxen from "boxen"
import yargs from "yargs"
import { hideBin } from "yargs/helpers"

import chalk from "chalk"
import contentful from 'contentful-management'

console.log(boxen(chalk.whiteBright("Switch Alias environment to a new version"), {padding: 1}));
const argv = await yargs(hideBin(process.argv))
.usage('Usage: $0 [options]')
.describe("a", "The environment alias to be switched to a new version")
.alias("a", "alias")
.boolean("rollback")
.alias("r", "rollback")
.help(true)
.version(false)
.example("$0 -a master", "Switch the master alias to the next (calculated) version of the environment it points to")
.example("$0 -a master -r", "Rollback the master alias to the previous (calculated) version")
.demandOption(["a"])
.argv;

const token = process.env.CONTENTFUL_MANAGEMENT_TOKEN as string
if (!token) throw new Error("No Contentful management API key specified, make sure you've set the CONTENTFUL_MANAGEMENT_ACCESS_TOKEN environment variable")

const spaceId = process.env.CPD_SPACE_ID as string
if (!spaceId) throw new Error("No space specified, make sure you've set the CPD_SPACE_ID environment variable")

const aliasId = argv.a as string
if (!aliasId) throw new Error("No alias specified")

console.log("Creating Contentful client")
const client = contentful.createClient({ accessToken: token })

console.log(`Fetching space`)
const space = await client.getSpace(spaceId)

console.log(`Fetching environment alias ${chalk.yellowBright(aliasId)}`)
const alias = await space.getEnvironmentAlias(argv.a as string)

console.log(`Fetching alias's target environment ${chalk.yellowBright(alias.environment.sys.id)}`)
const environment = await space.getEnvironment(alias.environment.sys.id)

console.log("Generating new environment name")

console.log(`Current Environment name is ${chalk.yellowBright(environment.name)}`)
const tokens = environment.name.split("__")
if (tokens === undefined) {
throw new Error(`${chalk.redBright("Error:")} Environment ${chalk.yellowBright(environment.sys.id)} is not in the correct format`)
}

let version = tokens.length > 1 ? parseInt(tokens[1]) : 1

let newEnvName = ''

if (argv.rollback) {
console.log("Rolling back version")
newEnvName = `${tokens[0]}__${version-1}`
if (version === 2) {
newEnvName = `${tokens[0]}`
}
} else {
console.log("Versioning for a release")
newEnvName = `${tokens[0]}__${version+1}`
}

//const newEnvName = `${tokens[0]}__${version+1}`
console.log(`New environment name will be ${chalk.yellowBright(newEnvName)}`)

console.log(`Checking that ${chalk.yellowBright(newEnvName)} exists`)
const newEnvironment = await space.getEnvironment(newEnvName)

console.log(`Switching alias ${chalk.yellowBright(aliasId)} to ${chalk.yellowBright(newEnvironment.name)}`)
alias.environment.sys.id = newEnvironment.sys.id
await alias.update()

console.log("Done")

0 comments on commit dc37bec

Please sign in to comment.