mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
[monorepo] add integration for GitHub Code Spaces (#32722)
* [web] serve site manifest as application/json * [monorepo] bail out early from dev-env-setup when inside devcontainer * [monorepo] move utils for waiting for services into shared bash script * [monorepo] move domain related env-vars into dedicated .env file The .env file will be overridden in GitHub Code Spaces. * [monorepo] remove unused initial_mongo_setup Make target It was previously used for the mongo replica set setup. That setup is a docker init script now. * [monorepo] add flag for silencing docker build output * [monorepo] add integration for GitHub Code Spaces * [web] make prettier happy * [web] restore no use-credentials for manifest outside code spaces * [monorepo] run make install as part of post-start again GitOrigin-RevId: 8c2cc3b969b7e3e8f9c5dac778192c9412cbf4df
This commit is contained in:
@@ -308,6 +308,7 @@ module.exports = {
|
||||
'scripts/delete_orphaned_chat_threads.mjs',
|
||||
'scripts/delete_orphaned_data_helper.mjs',
|
||||
'scripts/delete_subscriptions.mjs',
|
||||
'scripts/devcontainer_setup.mjs',
|
||||
'scripts/e2e_test_setup.mjs',
|
||||
'scripts/ensure_affiliations.mjs',
|
||||
'scripts/esm-check-migration.mjs',
|
||||
|
||||
@@ -147,4 +147,8 @@ if metadata && metadata.canonicalURL
|
||||
|
||||
//- Manifest
|
||||
//- Does not currently contain a start_url to prevent browser installation prompts
|
||||
link(rel='manifest' href=buildBaseAssetPath() + 'web.sitemanifest')
|
||||
link(
|
||||
rel='manifest'
|
||||
href=buildBaseAssetPath() + 'web.sitemanifest.json'
|
||||
crossorigin=settings.isCodeSpace ? 'use-credentials' : false
|
||||
)
|
||||
|
||||
@@ -327,6 +327,8 @@ module.exports = {
|
||||
// that are sent out, generated links, etc.
|
||||
siteUrl: (siteUrl = process.env.PUBLIC_URL || 'http://127.0.0.1:3000'),
|
||||
|
||||
isCodeSpace: process.env.IS_CODE_SPACE === 'true',
|
||||
|
||||
lockManager: {
|
||||
lockTestInterval: intFromEnv('LOCK_MANAGER_LOCK_TEST_INTERVAL', 50),
|
||||
maxTestInterval: intFromEnv('LOCK_MANAGER_MAX_TEST_INTERVAL', 1000),
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
"build-storybook": "storybook build",
|
||||
"build-unfilled-fonts": "node frontend/fonts/material-symbols/build-unfilled.mjs",
|
||||
"precompile-pug": "node app/src/infrastructure/Views.mjs",
|
||||
"local:nodemon": "set -a;. ../../config/dev-environment.env;. ./docker-compose.common.env;. ../../config/local-dev.env;. ./local-dev.env;. ../../config/local.env; set +a; echo $OVERLEAF_CONFIG; WEB_PORT=13000 LISTEN_ADDRESS=0.0.0.0 npm run nodemon",
|
||||
"local:webpack": "set -a;. ../../config/dev-environment.env;. ./docker-compose.common.env;. ../../config/local-dev.env;. ./local-dev.env;. ../../config/local.env; set +a; PORT=13808 OVERLEAF_CONFIG=$(pwd)/config/settings.webpack.js npm run webpack",
|
||||
"local:nodemon": "set -a;. ../../config/dev-environment.env;. ./docker-compose.common.env;. ../../config/local-dev.env;. ./local-dev.env;. ../../config/local.env;. ../../config/domain.env; set +a; echo $OVERLEAF_CONFIG; WEB_PORT=13000 LISTEN_ADDRESS=0.0.0.0 npm run nodemon",
|
||||
"local:webpack": "set -a;. ../../config/dev-environment.env;. ./docker-compose.common.env;. ../../config/local-dev.env;. ./local-dev.env;. ../../config/local.env;. ../../config/domain.env; set +a; PORT=13808 OVERLEAF_CONFIG=$(pwd)/config/settings.webpack.js npm run webpack",
|
||||
"local:test:acceptance:run_dir": "set -a;. $(pwd)/docker-compose.common.env;. $(pwd)/local-test.env; set +a; npm run test:acceptance:run_dir",
|
||||
"local:test:acceptance:run_app": "OVERLEAF_CONFIG=$(pwd)/test/acceptance/config/settings.test.${OVERLEAF_APP}.js npm run local:test:acceptance:run_dir -- $(pwd)/test/acceptance/src",
|
||||
"local:test:acceptance:run_module": "if [ ! -d $(pwd)/modules/${MODULE}/test/acceptance ]; then echo \"Module '${MODULE}' does not have acceptance tests\"; exit 0; fi; OVERLEAF_CONFIG=$(pwd)/modules/${MODULE}/test/acceptance/config/settings.test.js BASE_CONFIG=$(pwd)/test/acceptance/config/settings.test.${OVERLEAF_APP}.js npm run local:test:acceptance:run_dir -- $(pwd)/modules/${MODULE}/test/acceptance",
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "Overleaf",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#1b222c",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
18
services/web/public/web.sitemanifest.json
Normal file
18
services/web/public/web.sitemanifest.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Overleaf",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#1b222c",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
92
services/web/scripts/devcontainer_setup.mjs
Normal file
92
services/web/scripts/devcontainer_setup.mjs
Normal file
@@ -0,0 +1,92 @@
|
||||
import { promiseMapWithLimit } from '@overleaf/promise-utils'
|
||||
import Settings from '@overleaf/settings'
|
||||
import { waitForDb, db } from '../app/src/infrastructure/mongodb.mjs'
|
||||
import GracefulShutdown from '../app/src/infrastructure/GracefulShutdown.mjs'
|
||||
import UserRegistrationHandler from '../app/src/Features/User/UserRegistrationHandler.mjs'
|
||||
import minimist from 'minimist'
|
||||
import {
|
||||
createProjectWithOldHistoryId,
|
||||
provisionSplitTests,
|
||||
} from './e2e_test_setup.mjs'
|
||||
|
||||
const { email: USER_EMAIL, password: PASSWORD } = minimist(
|
||||
process.argv.slice(2),
|
||||
{ string: ['email', 'password'] }
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {string} email
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
async function createUser(email) {
|
||||
let userId
|
||||
try {
|
||||
const user = await UserRegistrationHandler.promises.registerNewUser({
|
||||
email,
|
||||
password: PASSWORD,
|
||||
})
|
||||
userId = user._id
|
||||
} catch (err) {
|
||||
if (err.message.includes('EmailAlreadyRegistered')) {
|
||||
userId = err.info.userId
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
const features = email.startsWith('free')
|
||||
? Settings.defaultFeatures
|
||||
: Settings.features.professional
|
||||
const isAdmin = email === USER_EMAIL || email === 'admin@overleaf.com'
|
||||
let adminRoles = []
|
||||
if (isAdmin) {
|
||||
adminRoles = ['engineering']
|
||||
}
|
||||
await db.users.updateOne(
|
||||
{ _id: userId },
|
||||
{
|
||||
$set: {
|
||||
// Set admin flag.
|
||||
isAdmin,
|
||||
adminRoles,
|
||||
// Override features.
|
||||
features,
|
||||
featuresOverrides: [{ features }],
|
||||
// disable AI features, does not work with custom GH Code Spaces domain.
|
||||
'aiFeatures.enabled': false,
|
||||
},
|
||||
}
|
||||
)
|
||||
return userId.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} email
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
async function provisionUser(email) {
|
||||
const userId = await createUser(email)
|
||||
await createProjectWithOldHistoryId(userId)
|
||||
}
|
||||
|
||||
async function provisionUsers() {
|
||||
const emails = [
|
||||
USER_EMAIL,
|
||||
'admin@overleaf.com',
|
||||
'free@overleaf.com',
|
||||
'premium@overleaf.com',
|
||||
]
|
||||
await promiseMapWithLimit(5, emails, provisionUser)
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
throw new Error('only available in dev-env')
|
||||
}
|
||||
await waitForDb()
|
||||
await Promise.all([provisionUsers(), provisionSplitTests()])
|
||||
}
|
||||
|
||||
if (import.meta.main) {
|
||||
await main()
|
||||
await GracefulShutdown.gracefulShutdown()
|
||||
}
|
||||
@@ -85,7 +85,7 @@ async function deleteUser(email) {
|
||||
await UserDeleter.promises.expireDeletedUser(user._id)
|
||||
}
|
||||
|
||||
async function createProjectWithOldHistoryId(userId) {
|
||||
export async function createProjectWithOldHistoryId(userId) {
|
||||
const projectName = 'old history id'
|
||||
const historyId = parseInt(
|
||||
await HistoryManager.promises.initializeProject(),
|
||||
@@ -137,7 +137,7 @@ async function purgeNewUsers() {
|
||||
)
|
||||
}
|
||||
|
||||
async function provisionSplitTests() {
|
||||
export async function provisionSplitTests() {
|
||||
const backup = Path.join(
|
||||
MONOREPO,
|
||||
'backup',
|
||||
@@ -213,12 +213,7 @@ async function main() {
|
||||
await Promise.all([purgeNewUsers(), provisionUsers(), provisionSplitTests()])
|
||||
}
|
||||
|
||||
await main()
|
||||
await GracefulShutdown.gracefulShutdown(
|
||||
{
|
||||
close(cb) {
|
||||
cb()
|
||||
},
|
||||
},
|
||||
'SIGTERM'
|
||||
)
|
||||
if (import.meta.main) {
|
||||
await main()
|
||||
await GracefulShutdown.gracefulShutdown()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user