Deployments

Deployments (or releases) may involve code changes at any and all levels of the codebase.

In terms of a full code deployment, all packages must be released. In practical application, a change might include changes specific to the CMS, the core components or anywhere in between.

For documentation purposes, we'll use a low-level dependency update as the catalyst for a release.

Use the following template as a guide. Code changes must be propagated to every subsequent repo in the following list:

Packages

The first few sections deal with the release of installable NPM packages. These packages can be released at any time and have no effect of customer facing features until the platform in which they're installed is deployed.

rebel-web-components

The @rebeldotcom/components package has no other Rebel-specific dependencies. Releases typically include a bump in external package versions, modifications in existing components or new components.

Once a PR is merged and the main branch is up to date and pushed to github, a new package can be published.

Using semantic versioning, there are three different deployment scripts: Major, minor and patch:

npm run deploy:patch
npm run deploy:minor

The major release script is not implemented at this point (we don't have an official v1 yet), but should follow this format.

npm run deploy:major
*Note: Publishing new versions of @rebeldotcom/components and @rebeldotcom/ui automatically bumps the version number in the package.json file and pushes to the main branch. Admin/Owner rights on the repo are necessary to do this. The same access rights should also be present on the package at [npmjs](https://www.npmjs.com/)

Once the release is done, the new version number is shown in the terminal. This is the new version to install into subsequent packages/platforms.

rebel-web-ui

Following the same set of scripts, the @rebeldotcom/ui package can be published by anyone with Admin/Owner rights on the repository.

As mentioned in the frontend overview, rebel-web-ui has a peer dependency of @rebeldotcom/components. If the code changes include a new version of the components package, the new version should be updated in both devDependencies and peerDependecies in the package.json file.

Platforms

There are currently two platforms (excluding this documentation service). The first is Rebel's modern CMS platform built in GatsbyJS and the second contains older React components to be run on RebelWeb(IIS)

rebel-web-cms

With the assumption that the components and/or ui packages have been released, they now have to be installed into the CMS project. This is done by modifying the package.json file to include the new versions and running"

npm install

Once this is done, a quick sanity check is recommended. Running locally is great for a quick visual check, but a build and serve performs a strict check and may highlight issues. These may go unnoticed when running locally and stop a build further in the deployment process.

Running locally:

npm start

Building and serving:

npm run build:serve

rebel-web-src

Similar to the rebel-web-cms project, both @rebeldotcom/components and @rebeldotcom/ui should stay up to date in the rebel-web-src project.

The following script is used to build the rebel-web-src bundles for local development:

npm run build:local

Differing from the local setup of the CMS, the rebel-web-src project is reliant on RebelWeb running on IIS.

Running the script above builds the bundles in the /dist folder of the application. A virtual folder should be created in IIS to map from the RebelWeb project to the rebel-web-src /dist folder containing the build.

CodeBuild and CodePipeline

Both rebel-web-cms and rebel-web-src use CodeBuild and CodePipeline for deployments. The configuration for each is in their respective /terraform folders.

rebel-web-cms creates three different

CloudFront

As we migrate pages over from IIS to GatsbyJS and need to direct traffic to the appropriate locations, we use AWS CloudFront behaviours at the page level.

As RebelWeb has/had the majority of routes, the initial idea is to create individual routes/behaviours within CloudFront for each page created within rebel-web-cms. Further, a rewrite rule must exist to support "/" and "/index.html" for the various pages.

The current steps necessary for a new CMS page to be released to production are as follows:

1. Create a new CloudFront behaviour in rebel-web-cms

The cloudfront.tf can be found at /terraform/modules/rebel-web-cms-pipeline/cloudfront.tf

All behaviours follow the same basic template:

ordered_cache_behavior {
    path_pattern    = "/managed-wordpress*"
    allowed_methods = ["GET", "HEAD"]
    cached_methods  = ["GET", "HEAD"]
    target_origin_id = "s3"

    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }

    min_ttl                = 86400
    default_ttl            = 86400
    max_ttl                = 31536000
    compress               = true
    viewer_protocol_policy = "redirect-to-https"

    lambda_function_association {
      event_type = "origin-request"
      lambda_arn = "${lookup(var.cloudfront_lambda, var.environment)}:${local.lambda_version}"
    }

    lambda_function_association {
      event_type = "viewer-response"
      lambda_arn = "${lookup(var.cloudfront_lambda, var.environment)}:${local.lambda_version}"
    }

    lambda_function_association {
      event_type = "viewer-request"
      lambda_arn = "${lookup(var.cloudfront_lambda, var.environment)}:${local.lambda_version}"
    }
  }
*Note: AWS has a limit for CF behaviours. Over time, we may need to request increases to this limit as the number grows.

2. Run the terraform deply script for the respective environments

There is a single script used to update the deployment infrastructure with a few args to allow for various options. The mandatory arg refers to the environment (AWS Account) to which the infrastructure is being deployed.

dev (Development):
cd ./terraform
./deploy.sh dev
master (Production):
cd ./terraform
./deploy.sh master
A Note on Branches

Deploying terraform not only changes the CloudFront infrastructure, but CodePipline, CodeBuild, etc... as well.

The default branch used for the pipelines is always main. In the event that a specific branch should be used for the pipeline, a second arg can be used:

./deploy.sh dev my-branch
*Note: CodeBuilds and CodePipelines are different things. A Build is created when the Pipeline runs. By deploying the changes to terraform as described in this seciton, we are NOT deploying code but simply tearing down and rebuilding the CodePipeline itself.
By redeploying the Pipeline with a different branch, we're simply changing the infrastructure to watch for changes on that specific branch to trigger the pipeline.

3. Merge a PR in the rewrites repository including the rewrite rule

Now that the code changes have been deployed to the cloud and CloudFront has been modifying to support the correct routing, a new page should be accessible via its direct path (ex: rebel.com/new-page/index.html)

In order to support the path without explicitly adding /index.html to the address, a rewrite rule must be added to rw-web-cloudfront-rewrite-redirects

*Note: The rewrite rule must be added to both reseller definitions. "internic" and "rebel"

See the current configurations for examples.

Once a PR in this repo is merged to the main branch, a CodePipeline is automatically triggered for both Production and Development.

At this point, the new slug should be accessible in the respective environments.

4. Sanity check. Always sanity check!

Seriously... just check your stuff.