mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 22:43:30 +03:00
eb9483abb6
no issue - When creating a dev container, the onCreateCommand script will try to setup the git remotes according to the environment variables defined for e.g. `$GHOST_UPSTREAM`. There was a bug that caused the `origin` remote to successfully be renamed to `$GHOST_UPSTREAM`, but the `origin` remote was not being created successfully on the first try. This commit fixes that bug.
243 lines
8.8 KiB
JavaScript
243 lines
8.8 KiB
JavaScript
// 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() {
|
|
setupGitRemotes();
|
|
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);
|
|
}
|
|
|
|
// Sets up the git remotes for the dev container based on environment variables
|
|
function setupGitRemotes() {
|
|
log('Configuring git remotes...', colors.blue);
|
|
try {
|
|
const GHOST_UPSTREAM = process.env.GHOST_UPSTREAM;
|
|
const GHOST_FORK_REMOTE_URL = process.env.GHOST_FORK_REMOTE_URL;
|
|
const GHOST_FORK_REMOTE_NAME = process.env.GHOST_FORK_REMOTE_NAME;
|
|
const GHOST_FORCE_SSH = process.env.GHOST_FORCE_SSH;
|
|
let remotes = execSync('git remote').toString().trim().split('\n');
|
|
|
|
if (GHOST_UPSTREAM) {
|
|
// Check if the upstream remote already exists
|
|
if (!remotes.includes(GHOST_UPSTREAM) && remotes.includes('origin')) {
|
|
log(`Renaming the default remote from origin to ${GHOST_UPSTREAM}...`, colors.blue);
|
|
execSync(`git remote rename origin ${GHOST_UPSTREAM}`);
|
|
}
|
|
}
|
|
|
|
remotes = execSync('git remote').toString().trim().split('\n');
|
|
if (GHOST_FORK_REMOTE_URL) {
|
|
const remoteName = GHOST_FORK_REMOTE_NAME || 'origin';
|
|
// Check if the fork remote already exists
|
|
if (!remotes.includes(remoteName)) {
|
|
log(`Adding fork remote ${GHOST_FORK_REMOTE_URL} as ${remoteName}...`, colors.blue);
|
|
execSync(`git remote add ${remoteName} ${GHOST_FORK_REMOTE_URL}`);
|
|
}
|
|
}
|
|
|
|
if (GHOST_FORCE_SSH) {
|
|
log('Forcing SSH for all remotes...', colors.blue);
|
|
// Get all remotes
|
|
remotes = execSync('git remote').toString().trim().split('\n');
|
|
|
|
for (const remote of remotes) {
|
|
// Get the current URL for this remote
|
|
const url = execSync(`git remote get-url ${remote}`).toString().trim();
|
|
|
|
// Only convert if it's an HTTPS URL
|
|
if (url.startsWith('https://')) {
|
|
// Convert HTTPS to SSH format
|
|
// https://github.com/user/repo.git -> git@github.com:user/repo.git
|
|
const sshUrl = url
|
|
.replace(/^https:\/\//, 'git@')
|
|
.replace(/\//, ':');
|
|
|
|
log(`Converting ${remote} from HTTPS to SSH...`, colors.dim);
|
|
execSync(`git remote set-url ${remote} ${sshUrl}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
} catch (error) {
|
|
logError('Error setting up git remotes:', 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' });
|
|
// Rename the default remote to $GHOST_UPSTREAM if it's set
|
|
// Otherwise `yarn main:submodules` will fail
|
|
const GHOST_UPSTREAM = process.env.GHOST_UPSTREAM;
|
|
if (GHOST_UPSTREAM) {
|
|
execSync(`git submodule foreach "git remote | grep -q '^${GHOST_UPSTREAM}$' || (git remote | grep -q '^origin$' && git remote rename origin ${GHOST_UPSTREAM})"`);
|
|
}
|
|
|
|
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(); |