Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ raisely.json
# dev folders
stylesheets
components
pages
.raisely.json
.env
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM node:12

WORKDIR /var/local

CMD ["tail", "-f", "/dev/null"]
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.PHONY: init update deploy start

init:
npm install
node ./bin/raisely init

update:
node ./bin/raisely update

deploy:
node ./bin/raisely deploy

start:
node ./bin/raisely start

26 changes: 21 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

![Raisely logo](https://raisely-themes.imgix.net/raisely/brand.raisely.svg)

The Raisely CLI is used to power local development of Raisely themes, syncing custom components and campaign styles to your local machine.
The Raisely CLI is used to power local development of Raisely themes, syncing custom components, campaign styles and pages to your local machine.

For more about Raisely, see <https://raisely.com>

## Overview

The Raisely CLI allows for fast and easy development on the Raisely platform. The CLI allows you to connect a directory on your local computer to a Raisely account. With the CLI you can update campaign stylesheets, and edit and create custom React components.
The Raisely CLI allows for fast and easy development on the Raisely platform. The CLI allows you to connect a directory on your local computer to a Raisely account. With the CLI you can update campaign stylesheets, pages and edit and create custom React components.

The CLI is built on Node.js, so you'll need Node.js installed to use it.

Expand All @@ -26,9 +26,9 @@ For other issues, [submit a support ticket](mailto:[email protected]).
## Commands

- `raisely init` - start a new Raisely project, authenticate and sync your campaigns
- `raisely update` - update local copies of styles and components from the API
- `raisely update` - update local copies of styles, pages and components from the API
- `raisely create [name]` - create a new custom component, optionally add the component name to the command (otherwise you will be asked for one)
- `raisely start` - starts watching for and uploading changes to styles and components
- `raisely start` - starts watching for and uploading changes to styles, pages and components

## CI/CD Usage

Expand All @@ -41,8 +41,24 @@ Raisely CLI supports the following environment variables:

_Note: All components are always synced, when they're present in the directory your syncing_

With these environment variables set, run: `raisely deploy`. This will sync your local directory to the remote Raisely account, overwriting the styles and components on the destination campaign.
With these environment variables set, run: `raisely deploy`. This will sync your local directory to the remote Raisely account, overwriting the styles, pages and components on the destination campaign.

## Developing

Contributions are welcome. The project is built with `commander`, `inquirer` and `ora` with a basic module structure.

### Local Development With Docker

Create a `.env` file in this directory containing the required environment variables:

RAISELY_TOKEN=

RAISELY_CAMPAIGNS=

then run `docker-compose up` from this directory.

In a new terminal window connect to the docker container:

`docker exec -it raisely-cli /bin/bash`

A Makefile provides tasks
15 changes: 15 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '2'

services:

raisely_cli:
container_name: "raisely_cli"
build:
context: .
dockerfile: Dockerfile
volumes:
- ".:/var/local"
environment:
- RAISELY_TOKEN=${RAISELY_TOKEN}
- RAISELY_CAMPAIGNS=${RAISELY_CAMPAIGNS}
restart: always
18 changes: 18 additions & 0 deletions src/actions/campaigns.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,21 @@ export async function updateStyles({ path, files, css }, config) {
config.apiUrl
);
}


export async function updatePage(page, config) {
return await api(
{
path: `/pages/${page.uuid}?private=true`,
method: "PATCH",
json: {
data: page.data
},
auth: {
bearer: config.token
}
},
config.apiUrl
);

}
76 changes: 76 additions & 0 deletions src/actions/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,79 @@ export async function syncComponents(config, workDir, filter) {
return error(e, loader);
}
}

export async function syncPages(config, workDir) {
const directory = path.join(workDir, "pages");
if (!fs.existsSync(directory)) {
fs.mkdirSync(directory);
}

const loader = ora("Downloading campaign pages...").start();
try {
for (const uuid of config.campaigns) {
const campaign = await api(
{
path: `/campaigns/${uuid}?private=true`,
auth: {
bearer: config.token
}
},
config.apiUrl
);

const campaignDir = path.join(directory, campaign.data.path);

if (!fs.existsSync(campaignDir)) {
fs.mkdirSync(campaignDir);
}

const pages = await api(
{
path: `/campaigns/${uuid}/pages`,
qs: {
private: 1,
limit: 100
},
auth: {
bearer: config.token
}
},
config.apiUrl
);

for (const page of pages.data) {
fs.writeFileSync(
path.join(campaignDir, `${page.internalTitle}.json`),
JSON.stringify(
{
uuid: page.uuid,
data: { // these are the editable page fields
title: page.title,
internalTitle: page.internalTitle,
body: page.body,
path: page.path,
status: page.status,
provider: page.provider,
condition: page.condition,
image: page.image,
metaTitle: page.metaTitle,
metaDescription: page.metaDescription,
socialTitle: page.socialTitle,
socialDescription: page.socialDescription
}
},
null,
4
)
);
}

}

loader.succeed();
} catch (e) {
console.log(e);
return error(e, loader);
}

}
26 changes: 24 additions & 2 deletions src/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import fs from "fs";
import path from "path";

import { welcome, log, br, error } from "./helpers";
import { buildStyles, getCampaign } from "./actions/campaigns";
import { buildStyles, getCampaign, updatePage } from "./actions/campaigns";
import {
updateComponentFile,
updateComponentConfig
Expand All @@ -28,7 +28,7 @@ export default function deploy(program) {
br();
}
log(
`You will overwrite the styles and components in your campaign.`,
`You will overwrite the styles, components and pages in your campaign.`,
"white"
);
br();
Expand Down Expand Up @@ -94,6 +94,28 @@ export default function deploy(program) {
loader.succeed();
}

// upload campaign pages
for (const campaignUuid of config.campaigns) {
const loader = ora(`Uploading pages for ${campaignUuid}`).start();
const campaign = await getCampaign(
{ uuid: campaignUuid },
config.token,
config
);

const pagesDir = path.join(process.cwd(), "pages");
const campaignDir = path.join(pagesDir, `${campaign.data.path}`);

for (const file of fs.readdirSync(campaignDir)) {
const pageData = JSON.parse(fs.readFileSync(
path.join(campaignDir, file),
"utf8"
))
await updatePage(pageData, config);
}
loader.succeed();
}

br();
log(`All done!`);
});
Expand Down
5 changes: 4 additions & 1 deletion src/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ora from "ora";
import { welcome, log, br, error } from "./helpers";
import { login } from "./actions/auth";
import { getCampaigns } from "./actions/campaigns";
import { syncStyles, syncComponents } from "./actions/sync";
import { syncStyles, syncComponents, syncPages } from "./actions/sync";
import { saveConfig } from "./config";

export default function init(program) {
Expand Down Expand Up @@ -95,6 +95,9 @@ export default function init(program) {
// sync down custom components
await syncComponents(config, process.cwd());

// sync down pages
await syncPages(config, process.cwd());

br();
log("All done! You can start development by running:", "green");
br();
Expand Down
24 changes: 23 additions & 1 deletion src/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import path from "path";
import glob from "glob-promise";

import { welcome, log, br, error } from "./helpers";
import { updateStyles, buildStyles } from "./actions/campaigns";
import { updateStyles, buildStyles, updatePage } from "./actions/campaigns";
import {
updateComponentFile,
updateComponentConfig
Expand Down Expand Up @@ -33,6 +33,7 @@ export default function start(program) {
// watch folders
const stylesDir = path.join(process.cwd(), "stylesheets");
const componentsDir = path.join(process.cwd(), "components");
const pagesDir = path.join(process.cwd(), "pages");
fs.watch(
stylesDir,
{ encoding: "utf8", recursive: true },
Expand Down Expand Up @@ -99,5 +100,26 @@ export default function start(program) {
loader.succeed();
}
);

fs.watch(
pagesDir,
{ encoding: "utf8", recursive: true },
async (eventType, filename) => {
const loader = ora(`Saving ${filename}`).start();
try {
const pageData = JSON.parse(fs.readFileSync(
path.join(pagesDir, `${filename}`),
"utf8"
))
await updatePage(pageData, config);
} catch (e) {
return error(e, loader);
}

loader.succeed();
}
);


});
}
5 changes: 4 additions & 1 deletion src/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import chalk from "chalk";
import inquirer from "inquirer";

import { welcome, log, br, error } from "./helpers";
import { syncStyles, syncComponents } from "./actions/sync";
import { syncStyles, syncComponents, syncPages } from "./actions/sync";
import { loadConfig } from "./config";

export default function update(program) {
Expand Down Expand Up @@ -48,6 +48,9 @@ export default function update(program) {
// sync down custom components
await syncComponents(config, process.cwd());

// sync down pages
await syncPages(config, process.cwd());

br();
log(
`All done! Run ${chalk.bold.underline.white(
Expand Down