Skip to content

Commit

Permalink
Merge branch 'TryGhost:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Lekler authored Sep 4, 2024
2 parents 61aabb8 + 00b2378 commit be93b06
Show file tree
Hide file tree
Showing 2,421 changed files with 93,568 additions and 64,465 deletions.
5 changes: 0 additions & 5 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,3 @@ Please include a description of your change & check your PR against this list, t
- [ ] The build will pass (run `yarn test:all` and `yarn lint`)

We appreciate your contribution!

---

<!-- Leave the line below if you'd like GitHub Copilot to generate a summary from your commit -->
copilot:summary
4 changes: 2 additions & 2 deletions .github/actions/restore-cache/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ runs:
steps:
- name: Check dependency cache
id: dep-cache
uses: actions/cache/restore@v3
uses: actions/cache/restore@v4
with:
path: ${{ env.CACHED_DEPENDENCY_PATHS }}
key: ${{ env.DEPENDENCY_CACHE_KEY }}

- name: Check build cache
uses: actions/cache/restore@v3
uses: actions/cache/restore@v4
id: build-cache
with:
path: ${{ env.CACHED_BUILD_PATHS }}
Expand Down
59 changes: 44 additions & 15 deletions .github/scripts/dev.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const fs = require('fs');
const path = require('path');
const util = require('util');
const exec = util.promisify(require('child_process').exec);

const chalk = require('chalk');
const concurrently = require('concurrently');

// check we're running on Node 18 and above
Expand All @@ -15,6 +17,20 @@ const config = require('../../ghost/core/core/shared/config/loader').loadNconf({
customConfigPath: path.join(__dirname, '../../ghost/core')
});

const tsPackages = fs.readdirSync(path.resolve(__dirname, '../../ghost'), {withFileTypes: true})
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name)
.filter(packageFolder => {
try {
const packageJson = require(path.resolve(__dirname, `../../ghost/${packageFolder}/package.json`));
return packageJson.scripts?.['build:ts'];
} catch (err) {
return false;
}
})
.map(packageFolder => `ghost/${packageFolder}`)
.join(',');

const liveReloadBaseUrl = config.getSubdir() || '/ghost/';
const siteUrl = config.getSiteUrl();

Expand Down Expand Up @@ -44,32 +60,40 @@ const COMMAND_ADMIN = {

const COMMAND_TYPESCRIPT = {
name: 'ts',
command: 'nx watch --projects=ghost/collections,ghost/in-memory-repository,ghost/bookshelf-repository,ghost/mail-events,ghost/model-to-domain-event-interceptor,ghost/post-revisions,ghost/nql-filter-expansions,ghost/post-events,ghost/donations,ghost/recommendations -- nx run \\$NX_PROJECT_NAME:build:ts',
command: `while [ 1 ]; do nx watch --projects=${tsPackages} -- nx run \\$NX_PROJECT_NAME:build:ts; done`,
cwd: path.resolve(__dirname, '../../'),
prefixColor: 'cyan',
env: {}
};

const COMMAND_ADMINX = {
const adminXApps = '@tryghost/admin-x-demo,@tryghost/admin-x-settings,@tryghost/admin-x-activitypub';

const COMMANDS_ADMINX = [{
name: 'adminXDeps',
command: 'while [ 1 ]; do nx watch --projects=apps/admin-x-design-system,apps/admin-x-framework -- nx run \\$NX_PROJECT_NAME:build; done',
cwd: path.resolve(__dirname, '../..'),
prefixColor: '#C72AF7',
env: {}
}, {
name: 'adminX',
command: 'yarn dev',
cwd: path.resolve(__dirname, '../../apps/admin-x-settings'),
prefixColor: '#C35831',
command: `nx run-many --projects=${adminXApps} --parallel=${adminXApps.length} --targets=dev`,
cwd: path.resolve(__dirname, '../../apps/admin-x-settings', '../../apps/admin-x-activitypub'),
prefixColor: '#C72AF7',
env: {}
};
}];

if (DASH_DASH_ARGS.includes('ghost')) {
commands = [COMMAND_GHOST, COMMAND_TYPESCRIPT];
} else if (DASH_DASH_ARGS.includes('admin')) {
commands = [COMMAND_ADMIN, COMMAND_ADMINX];
commands = [COMMAND_ADMIN, ...COMMANDS_ADMINX];
} else {
commands = [COMMAND_GHOST, COMMAND_TYPESCRIPT, COMMAND_ADMIN, COMMAND_ADMINX];
commands = [COMMAND_GHOST, COMMAND_TYPESCRIPT, COMMAND_ADMIN, ...COMMANDS_ADMINX];
}

if (DASH_DASH_ARGS.includes('portal') || DASH_DASH_ARGS.includes('all')) {
commands.push({
name: 'portal',
command: 'yarn dev',
command: 'nx run @tryghost/portal:dev',
cwd: path.resolve(__dirname, '../../apps/portal'),
prefixColor: 'magenta',
env: {}
Expand All @@ -92,7 +116,7 @@ if (DASH_DASH_ARGS.includes('portal') || DASH_DASH_ARGS.includes('all')) {
if (DASH_DASH_ARGS.includes('signup') || DASH_DASH_ARGS.includes('all')) {
commands.push({
name: 'signup-form',
command: DASH_DASH_ARGS.includes('signup') ? 'yarn dev' : 'yarn preview',
command: DASH_DASH_ARGS.includes('signup') ? 'nx run @tryghost/signup-form:dev' : 'nx run @tryghost/signup-form:preview',
cwd: path.resolve(__dirname, '../../apps/signup-form'),
prefixColor: 'magenta',
env: {}
Expand All @@ -103,7 +127,7 @@ if (DASH_DASH_ARGS.includes('signup') || DASH_DASH_ARGS.includes('all')) {
if (DASH_DASH_ARGS.includes('announcement-bar') || DASH_DASH_ARGS.includes('announcementBar') || DASH_DASH_ARGS.includes('announcementbar') || DASH_DASH_ARGS.includes('all')) {
commands.push({
name: 'announcement-bar',
command: 'yarn dev',
command: 'nx run @tryghost/announcement-bar:dev',
cwd: path.resolve(__dirname, '../../apps/announcement-bar'),
prefixColor: '#DC9D00',
env: {}
Expand All @@ -114,7 +138,7 @@ if (DASH_DASH_ARGS.includes('announcement-bar') || DASH_DASH_ARGS.includes('anno
if (DASH_DASH_ARGS.includes('search') || DASH_DASH_ARGS.includes('all')) {
commands.push({
name: 'search',
command: 'yarn dev',
command: 'nx run @tryghost/sodo-search:dev',
cwd: path.resolve(__dirname, '../../apps/sodo-search'),
prefixColor: '#23de43',
env: {}
Expand Down Expand Up @@ -153,7 +177,7 @@ if (DASH_DASH_ARGS.includes('comments') || DASH_DASH_ARGS.includes('all')) {

commands.push({
name: 'comments',
command: 'yarn dev',
command: 'nx run @tryghost/comments-ui:dev',
cwd: path.resolve(__dirname, '../../apps/comments-ui'),
prefixColor: '#E55137',
env: {}
Expand All @@ -165,7 +189,6 @@ async function handleStripe() {
if (DASH_DASH_ARGS.includes('offline')) {
return;
}
console.log('Fetching Stripe secret token..');

let stripeSecret;
try {
Expand Down Expand Up @@ -198,6 +221,8 @@ async function handleStripe() {
process.exit(0);
}

console.log(`Running projects: ${commands.map(c => chalk.green(c.name)).join(', ')}`);

const {result} = concurrently(commands, {
prefix: 'name',
killOthers: ['failure', 'success']
Expand All @@ -206,6 +231,10 @@ async function handleStripe() {
try {
await result;
} catch (err) {
console.error('\nExecuting dev command failed, ensure dependencies are up-to-date by running `yarn fix`\n');
console.error();
console.error(chalk.red(`Executing dev command failed:`) + `\n`);
console.error(chalk.red(`If you've recently done a \`yarn main\`, dependencies might be out of sync. Try running \`${chalk.green('yarn fix')}\` to fix this.`));
console.error(chalk.red(`If not, something else went wrong. Please report this to the Ghost team.`));
console.error();
}
})();
39 changes: 39 additions & 0 deletions .github/scripts/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: '3.8'

name: ghost

services:
mysql:
image: mysql:8.0.35
container_name: ghost-mysql
# We'll need to look into how we can further fine tune the memory usage/performance here
command: --innodb-buffer-pool-size=1G --innodb-log-buffer-size=500M --innodb-change-buffer-max-size=50 --innodb-flush-log-at-trx_commit=0 --innodb-flush-method=O_DIRECT
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: ghost
restart: always
volumes:
# Turns out you can drop .sql or .sql.gz files in here, cool!
- ./mysql-preload:/docker-entrypoint-initdb.d
healthcheck:
test: "mysql -uroot -proot ghost -e 'select 1'"
interval: 1s
retries: 120
redis:
image: redis:7.0
container_name: ghost-redis
ports:
- "6379:6379"
restart: always
jaeger:
image: jaegertracing/all-in-one:1.58
container_name: ghost-jaeger
ports:
- "4318:4318"
- "16686:16686"
- "9411:9411"
restart: always
environment:
COLLECTOR_ZIPKIN_HOST_PORT: :9411
Empty file.
138 changes: 138 additions & 0 deletions .github/scripts/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
const {spawn} = require('child_process');
const fs = require('fs').promises;
const path = require('path');

const chalk = require('chalk');
const inquirer = require('inquirer');

/**
* Run a command and stream output to the console
*
* @param {string} command
* @param {string[]} args
* @param {object} options
*/
async function runAndStream(command, args, options) {
return new Promise((resolve, reject) => {
const child = spawn(command, args, {
stdio: 'inherit',
...options
});

child.on('close', (code) => {
if (code === 0) {
resolve(code);
} else {
reject(new Error(`'${command} ${args.join(' ')}' exited with code ${code}`));
}
});

});
}

(async () => {
if (process.env.NODE_ENV !== 'development') {
console.log(chalk.yellow(`NODE_ENV is not development, skipping setup`));
return;
}

const coreFolder = path.join(__dirname, '../../ghost/core');
const rootFolder = path.join(__dirname, '../..');
const config = require('../../ghost/core/core/shared/config/loader').loadNconf({
customConfigPath: coreFolder
});

const dbClient = config.get('database:client');
const isUsingDocker = config.get('database:docker');

// Only reset data if we are using Docker
let resetData = false;

if (!dbClient.includes('mysql')) {
let mysqlSetup = false;
console.log(chalk.blue(`Attempting to setup MySQL via Docker`));
try {
await runAndStream('yarn', ['docker:reset'], {cwd: path.join(__dirname, '../../')});
mysqlSetup = true;
} catch (err) {
console.error(chalk.red('Failed to run MySQL Docker container'), err);
console.error(chalk.red('Hint: is Docker installed and running?'));
}

if (mysqlSetup) {
resetData = true;
console.log(chalk.blue(`Adding MySQL credentials to config.local.json`));
const currentConfigPath = path.join(coreFolder, 'config.local.json');

let currentConfig;
try {
currentConfig = require(currentConfigPath);
} catch (err) {
currentConfig = {};
}

currentConfig.database = {
client: 'mysql',
docker: true,
connection: {
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'ghost'
}
};

try {
await fs.writeFile(currentConfigPath, JSON.stringify(currentConfig, null, 4));
} catch (err) {
console.error(chalk.red('Failed to write config.local.json'), err);
console.log(chalk.yellow(`Please add the following to config.local.json:\n`), JSON.stringify(currentConfig, null, 4));
process.exit(1);
}
}
} else {
if (isUsingDocker) {
const yesAll = process.argv.includes('-y');
const noAll = process.argv.includes('-n');
const {confirmed} =
yesAll ? {confirmed: true}
: (
noAll ? {confirmed: false}
: await inquirer.prompt({name: 'confirmed', type:'confirm', message: 'MySQL is running via Docker, do you want to reset the Docker container? This will delete all existing data.', default: false})
);

if (confirmed) {
console.log(chalk.yellow(`Resetting Docker container`));

try {
await runAndStream('yarn', ['docker:reset'], {cwd: path.join(__dirname, '../../')});
resetData = true;
} catch (err) {
console.error(chalk.red('Failed to run MySQL Docker container'), err);
console.error(chalk.red('Hint: is Docker installed and running?'));
}
}
} else {
console.log(chalk.green(`MySQL already configured locally. Stop your local database and delete your "database" configuration in config.local.json to switch to Docker.`));
}
}

console.log(chalk.blue(`Running knex-migrator init`));
await runAndStream('yarn', ['knex-migrator', 'init'], {cwd: coreFolder});
if (process.argv.includes('--no-seed')) {
console.log(chalk.yellow(`Skipping seed data`));
console.log(chalk.yellow(`Done`));
return;
}
if (resetData) {
const xxl = process.argv.includes('--xxl');

if (xxl) {
console.log(chalk.blue(`Resetting all data (with xxl)`));
await runAndStream('yarn', ['reset:data:xxl'], {cwd: rootFolder});
} else {
console.log(chalk.blue(`Resetting all data`));
await runAndStream('yarn', ['reset:data'], {cwd: rootFolder});
}
}
})();
Loading

0 comments on commit be93b06

Please sign in to comment.