0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Converted dev container's onCreateCommand to JavaScript (#21457)

no issue

- The onCreateCommand was previously a bash script, which made it a bit
more challenging to read and make changes to it. This commit converts it
to JavaScript so it will be easier to make updates to it.
This commit is contained in:
Chris Raible 2024-10-29 13:03:49 -07:00 committed by GitHub
parent 856dd1fc2b
commit 71fb9f8b34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 180 additions and 112 deletions

View file

@ -1,93 +0,0 @@
const fs = require('fs');
const path = require('path');
const assert = require('node:assert/strict');
// Reads the config.local.json file and updates it with environments variables for devcontainer setup
const configBasePath = path.join(__dirname, '..', 'ghost', 'core');
const configFile = path.join(configBasePath, 'config.local.json');
let originalConfig = {};
if (fs.existsSync(configFile)) {
try {
// Backup the user's config.local.json file just in case
// This won't be used by Ghost but can be useful to switch back to local development
const backupFile = path.join(configBasePath, 'config.local-backup.json');
fs.copyFileSync(configFile, backupFile);
// Read the current config.local.json file into memory
const fileContent = fs.readFileSync(configFile, 'utf8');
originalConfig = JSON.parse(fileContent);
} catch (error) {
console.error('Error reading or parsing config file:', error);
process.exit(1);
}
} else {
console.log('Config file does not exist. Creating a new one.');
}
let newConfig = {};
// Change the url if we're in a codespace
if (process.env.CODESPACES === 'true') {
assert.ok(process.env.CODESPACE_NAME, 'CODESPACE_NAME is not defined');
assert.ok(process.env.GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN, 'GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN is not defined');
const url = `https://${process.env.CODESPACE_NAME}-2368.${process.env.GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}`;
newConfig.url = url;
}
newConfig.database = {
client: 'mysql2',
connection: {
host: 'mysql',
user: 'root',
password: 'root',
database: 'ghost'
}
}
newConfig.adapters = {
Redis: {
host: 'redis',
port: 6379
}
}
// Only update the mail settings if they aren't already set
if (!originalConfig.mail && process.env.MAILGUN_SMTP_PASS && process.env.MAILGUN_SMTP_USER && process.env.MAILGUN_FROM_ADDRESS) {
newConfig.mail = {
transport: 'SMTP',
from: process.env.MAILGUN_FROM_ADDRESS,
options: {
service: 'Mailgun',
host: 'smtp.mailgun.org',
secure: true,
port: 465,
auth: {
user: process.env.MAILGUN_SMTP_USER,
pass: process.env.MAILGUN_SMTP_PASS
}
}
}
}
// Only update the bulk email settings if they aren't already set
if (!originalConfig.bulkEmail && process.env.MAILGUN_API_KEY && process.env.MAILGUN_DOMAIN) {
newConfig.bulkEmail = {
mailgun: {
baseUrl: 'https://api.mailgun.net/v3',
apiKey: process.env.MAILGUN_API_KEY,
domain: process.env.MAILGUN_DOMAIN,
tag: 'bulk-email'
}
}
}
// Merge the original config with the new config
const config = {...originalConfig, ...newConfig};
// Write the updated config.local.json file
try {
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
console.log('Config file updated successfully.');
} catch (error) {
console.error('Error writing config file:', error);
process.exit(1);
}

View file

@ -4,7 +4,7 @@
"service": "ghost",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"shutdownAction": "stopCompose",
"onCreateCommand": ["./.devcontainer/onCreateCommand.sh"],
"onCreateCommand": ["node", "./.devcontainer/onCreateCommand.js"],
"updateContentCommand": ["git", "submodule", "update", "--init", "--recursive"],
"postCreateCommand": ["yarn", "knex-migrator", "init"],
"remoteEnv": {

View file

@ -0,0 +1,179 @@
// This script is run in the Dev Container right after it is created
// No dependencies are installed at this point so we can't use any npm packages
const fs = require('fs');
const path = require('path');
const assert = require('node:assert/strict');
const { execSync } = require('child_process');
// Main function that runs all the setup steps
function main() {
setupLocalConfig();
runCleanHard();
runInstall();
runSubmoduleUpdate();
runTypescriptBuild();
}
// Basic color constants for console output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
dim: '\x1b[2m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m',
};
function log(message, color = colors.reset) {
console.log(`${color}${message}${colors.reset}`);
}
function logError(message, error) {
console.error(`${colors.red}${message}${colors.reset}`, error);
}
// Creates config.local.json file with the correct values for the devcontainer
function setupLocalConfig() {
log('Setting up local config file...', colors.blue);
// Reads the config.local.json file and updates it with environments variables for devcontainer setup
const configBasePath = path.join(__dirname, '..', 'ghost', 'core');
const configFile = path.join(configBasePath, 'config.local.json');
let originalConfig = {};
if (fs.existsSync(configFile)) {
try {
// Backup the user's config.local.json file just in case
// This won't be used by Ghost but can be useful to switch back to local development
const backupFile = path.join(configBasePath, 'config.local-backup.json');
fs.copyFileSync(configFile, backupFile);
// Read the current config.local.json file into memory
const fileContent = fs.readFileSync(configFile, 'utf8');
originalConfig = JSON.parse(fileContent);
} catch (error) {
logError('Error reading or parsing config file:', error);
process.exit(1);
}
} else {
log('Config file does not exist. Creating a new one.', colors.dim);
}
let newConfig = {};
// Change the url if we're in a codespace
if (process.env.CODESPACES === 'true') {
assert.ok(process.env.CODESPACE_NAME, 'CODESPACE_NAME is not defined');
assert.ok(process.env.GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN, 'GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN is not defined');
const url = `https://${process.env.CODESPACE_NAME}-2368.${process.env.GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}`;
newConfig.url = url;
}
newConfig.database = {
client: 'mysql2',
connection: {
host: 'mysql',
user: 'root',
password: 'root',
database: 'ghost'
}
}
newConfig.adapters = {
Redis: {
host: 'redis',
port: 6379
}
}
// Only update the mail settings if they aren't already set
if (!originalConfig.mail && process.env.MAILGUN_SMTP_PASS && process.env.MAILGUN_SMTP_USER && process.env.MAILGUN_FROM_ADDRESS) {
newConfig.mail = {
transport: 'SMTP',
from: process.env.MAILGUN_FROM_ADDRESS,
options: {
service: 'Mailgun',
host: 'smtp.mailgun.org',
secure: true,
port: 465,
auth: {
user: process.env.MAILGUN_SMTP_USER,
pass: process.env.MAILGUN_SMTP_PASS
}
}
}
}
// Only update the bulk email settings if they aren't already set
if (!originalConfig.bulkEmail && process.env.MAILGUN_API_KEY && process.env.MAILGUN_DOMAIN) {
newConfig.bulkEmail = {
mailgun: {
baseUrl: 'https://api.mailgun.net/v3',
apiKey: process.env.MAILGUN_API_KEY,
domain: process.env.MAILGUN_DOMAIN,
tag: 'bulk-email'
}
}
}
// Merge the original config with the new config
const config = {...originalConfig, ...newConfig};
// Write the updated config.local.json file
try {
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
log('Config file updated successfully.', colors.dim);
} catch (error) {
logError('Error writing config file:', error);
process.exit(1);
}
}
// Deletes node_modules and clears yarn & nx caches
function runCleanHard() {
try {
log('Cleaning up node_modules and yarn/nx caches...', colors.blue);
execSync('yarn clean:hard', { stdio: 'inherit' });
log('Successfully ran yarn clean:hard', colors.dim);
} catch (error) {
logError('Error running yarn clean:hard:', error);
process.exit(1);
}
}
// Installs dependencies
function runInstall() {
try {
log('Installing dependencies...', colors.blue);
execSync('yarn install --frozen-lockfile', { stdio: 'inherit' });
log('Successfully ran yarn install', colors.dim);
} catch (error) {
logError('Error running yarn install:', error);
process.exit(1);
}
}
// Initializes and updates git submodules
function runSubmoduleUpdate() {
try {
log('Updating git submodules...', colors.blue);
execSync('git submodule update --init --recursive', { stdio: 'inherit' });
log('Successfully ran git submodule update', colors.dim);
} catch (error) {
logError('Error running git submodule update:', error);
process.exit(1);
}
}
// Builds the typescript packages
function runTypescriptBuild() {
try {
log('Building typescript packages...', colors.blue);
execSync('yarn nx run-many -t build:ts', { stdio: 'inherit' });
log('Successfully ran yarn nx run-many -t build:ts', colors.dim);
} catch (error) {
logError('Error running yarn nx run-many -t build:ts:', error);
process.exit(1);
}
}
main();

View file

@ -1,18 +0,0 @@
#!/bin/bash
set -e
echo "Setting up local config file..."
node .devcontainer/createLocalConfig.js
echo "Cleaning up any previous installs..."
yarn clean:hard
echo "Installing dependencies..."
yarn install
echo "Updating git submodules..."
git submodule update --init --recursive
echo "Building typescript packages..."
yarn nx run-many -t build:ts