UBER-477: Uberflow dependencies (#3440)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2023-06-20 12:47:00 +07:00 committed by GitHub
parent 0bc097fc52
commit 2eab0fc71f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 329 additions and 117 deletions

2
.gitattributes vendored
View File

@ -1,6 +1,6 @@
# Don't allow people to merge changes to these generated files, because the result
# may be invalid. You need to run "rush update" again.
pnpm-lock.yaml merge=binary
pnpm-lock.yaml merge=text
shrinkwrap.yaml merge=binary
npm-shrinkwrap.json merge=binary
yarn.lock merge=binary

View File

@ -10,11 +10,11 @@ concurrency:
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [main, develop]
branches: [main]
tags:
- v*
pull_request:
branches: [main, develop]
branches: [main]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
@ -205,14 +205,7 @@ jobs:
mongodb-version: 5.0
- name: Testing...
uses: paambaati/codeclimate-action@v3.2.0
env:
CC_TEST_REPORTER_ID: 346a83855d7124e9da8e6ec36a4fd01dc432f5cdc755eb28da7d9c44da9d1142
with:
coverageCommand: node common/scripts/install-run-rush.js test --verbose
coverageLocations: |
${{github.workspace}}/packages/*/coverage/lcov.info:lcov
${{github.workspace}}/server/*/coverage/lcov.info:lcov
run: node common/scripts/install-run-rush.js test --verbose
uitest:
needs: build
runs-on: ubuntu-latest
@ -282,12 +275,12 @@ jobs:
with:
name: playwright-results
path: ./tests/sanity/playwright-report/
- name: Upload DB snapshot
if: always()
uses: actions/upload-artifact@v3
with:
name: db-snapshot
path: ./tests/db_dump
# - name: Upload DB snapshot
# if: always()
# uses: actions/upload-artifact@v3
# with:
# name: db-snapshot
# path: ./tests/db_dump
docker-build:
if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v') }}
needs: [build, uitest, test, svelte-check]

View File

@ -0,0 +1,20 @@
# This config file is very similar to common/config/rush/.npmrc, except that .npmrc-publish
# is used by the "rush publish" command, as publishing often involves different credentials
# and registries than other operations.
#
# Before invoking the package manager, Rush will copy this file to "common/temp/publish-home/.npmrc"
# and then temporarily map that folder as the "home directory" for the current user account.
# This enables the same settings to apply for each project folder that gets published. The copied file
# will omit any config lines that reference environment variables that are undefined in that session;
# this avoids problems that would otherwise result due to a missing variable being replaced by
# an empty string.
#
# * * * SECURITY WARNING * * *
#
# It is NOT recommended to store authentication tokens in a text file on a lab machine, because
# other unrelated processes may be able to read the file. Also, the file may persist indefinitely,
# for example if the machine loses power. A safer practice is to pass the token via an
# environment variable, which can be referenced from .npmrc using ${} expansion. For example:
#
# //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}
#

View File

@ -46,6 +46,14 @@
*/
"artifactoryWebsiteUrl": "",
/**
* Uncomment this line to specify the type of credential to save in the user's ~/.npmrc file.
* The default is "password", which means the user's API token will be traded in for an
* npm password specific to that registry. Optionally you can specify "authToken", which
* will save the user's API token as credentials instead.
*/
// "credentialType": "password",
/**
* These settings allow the "rush setup" interactive prompts to be customized, for
* example with messages specific to your team or configuration. Specify an empty string
@ -57,11 +65,13 @@
* "This monorepo consumes packages from an Artifactory private NPM registry."
*/
// "introduction": "",
/**
* Overrides the message that normally says:
* "Please contact the repository maintainers for help with setting up an Artifactory user account."
*/
// "obtainAnAccount": "",
/**
* Overrides the message that normally says:
* "Please open this URL in your web browser:"
@ -69,17 +79,31 @@
* The "artifactoryWebsiteUrl" string is printed after this message.
*/
// "visitWebsite": "",
/**
* Overrides the message that normally says:
* "Your user name appears in the upper-right corner of the JFrog website."
*/
// "locateUserName": "",
/**
* Overrides the message that normally says:
* "Click 'Edit Profile' on the JFrog website. Click the 'Generate API Key'
* button if you haven't already done so previously."
*/
// "locateApiKey": ""
/**
* Overrides the message that normally prompts:
* "What is your Artifactory user name?"
*/
// "userNamePrompt": ""
/**
* Overrides the message that normally prompts:
* "What is your Artifactory API key?"
*/
// "apiKeyPrompt": ""
}
}
}

View File

@ -2,7 +2,7 @@
* This configuration file manages Rush's build cache feature.
* More documentation is available on the Rush website: https://rushjs.io
*/
{
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/build-cache.schema.json",
/**
@ -21,9 +21,16 @@
/**
* Setting this property overrides the cache entry ID. If this property is set, it must contain
* a [hash] token. It may also contain a [projectName] or a [projectName:normalize] token.
* a [hash] token.
*
* Other available tokens:
* - [projectName]
* - [projectName:normalize]
* - [phaseName]
* - [phaseName:normalize]
* - [phaseName:trimPrefix]
*/
"cacheEntryNamePattern": "[projectName:normalize]-[hash]",
// "cacheEntryNamePattern": "[projectName:normalize]-[phaseName:normalize]-[hash]"
/**
* Use this configuration with "cacheProvider"="azure-blob-storage"
@ -62,17 +69,26 @@
*/
"amazonS3Configuration": {
/**
* (Required) The Amazon S3 region of the bucket to use for build cache (e.g. "us-east-1").
* (Required unless s3Endpoint is specified) The name of the bucket to use for build cache.
* Example: "my-bucket"
*/
// "s3Bucket": "my-bucket",
/**
* (Required unless s3Bucket is specified) The Amazon S3 endpoint of the bucket to use for build cache.
* This should not include any path; use the s3Prefix to set the path.
* Examples: "my-bucket.s3.us-east-2.amazonaws.com" or "http://localhost:9000"
*/
// "s3Endpoint": "https://my-bucket.s3.us-east-2.amazonaws.com",
/**
* (Required) The Amazon S3 region of the bucket to use for build cache.
* Example: "us-east-1"
*/
// "s3Region": "us-east-1",
/**
* The name of the bucket in Amazon S3 to use for build cache.
*/
// (Required) "s3Bucket": "my-bucket",
/**
* An optional prefix ("folder") for cache items.
* An optional prefix ("folder") for cache items. It should not start with "/".
*/
// "s3Prefix": "my-prefix",
@ -80,5 +96,48 @@
* If set to true, allow writing to the cache. Defaults to false.
*/
// "isCacheWriteAllowed": true
},
/**
* Use this configuration with "cacheProvider"="http"
*/
"httpConfiguration": {
/**
* (Required) The URL of the server that stores the caches.
* Example: "https://build-cacches.example.com/"
*/
// "url": "https://build-cacches.example.com/",
/**
* (Optional) The HTTP method to use when writing to the cache (defaults to PUT).
* Should be one of PUT, POST, or PATCH.
* Example: "PUT"
*/
// "uploadMethod": "PUT",
/**
* (Optional) HTTP headers to pass to the cache server.
* Example: { "X-HTTP-Company-Id": "109283" }
*/
// "headers": {},
/**
* (Optional) Shell command that prints the authorization token needed to communicate with the
* cache server, and exits with exit code 0. This command will be executed from the root of
* the monorepo.
* Example: { "exec": "node", "args": ["common/scripts/auth.js"] }
*/
// "tokenHandler": { "exec": "node", "args": ["common/scripts/auth.js"] },
/**
* (Optional) Prefix for cache keys.
* Example: "my-company-"
*/
// "cacheKeyPrefix": "",
/**
* (Optional) If set to true, allow writing to the cache. Defaults to false.
*/
// "isCacheWriteAllowed": true
}
}

View File

@ -28,5 +28,33 @@
* If true, the chmod field in temporary project tar headers will not be normalized.
* This normalization can help ensure consistent tarball integrity across platforms.
*/
// "noChmodFieldInTarHeaderNormalization": true
// "noChmodFieldInTarHeaderNormalization": true,
/**
* If true, build caching will respect the allowWarningsInSuccessfulBuild flag and cache builds with warnings.
* This will not replay warnings from the cached build.
*/
// "buildCacheWithAllowWarningsInSuccessfulBuild": true,
/**
* If true, the phased commands feature is enabled. To use this feature, create a "phased" command
* in common/config/rush/command-line.json.
*/
"phasedCommands": true,
/**
* If true, perform a clean install after when running `rush install` or `rush update` if the
* `.npmrc` file has changed since the last install.
*/
// "cleanInstallAfterNpmrcChanges": true,
/**
* If true, print the outputs of shell commands defined in event hooks to the console.
*/
// "printEventHooksOutputToConsole": true,
/**
* If true, Rush will not allow node_modules in the repo folder or in parent folders.
*/
// "forbidPhantomResolvableNodeModulesFolders": true
}

View File

@ -18727,13 +18727,14 @@ packages:
dev: false
file:projects/minio.tgz:
resolution: {integrity: sha512-96cz8nKgyHNMc6UQeMrIlPof2LUv8btuUhg6JHXQs19caEbFGRDajG8tbJZ83Mm8eQHP2CBwDDXgP3hlDDK62g==, tarball: file:projects/minio.tgz}
resolution: {integrity: sha512-HDxYF3wfgSvuq+57ZoxfNDaC92St3f+/ybevhmwexFmiDEyyQNN4pMZi0LtOkjLiP4bNJ1tLkkb9ooQc1pr+VA==, tarball: file:projects/minio.tgz}
name: '@rush-temp/minio'
version: 0.0.0
dependencies:
'@rushstack/heft': 0.47.11
'@types/heft-jest': 1.0.3
'@types/minio': 7.0.14
'@types/node': 16.11.68
'@typescript-eslint/eslint-plugin': 5.42.1_d506b9be61cb4ac2646ecbc6e0680464
'@typescript-eslint/parser': 5.42.1_eslint@8.27.0+typescript@4.8.4
eslint: 8.27.0

View File

@ -0,0 +1,29 @@
/**
* This configuration file manages Rush's plugin feature.
*/
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugins.schema.json",
"plugins": [
/**
* Each item configures a plugin to be loaded by Rush.
*/
// {
// /**
// * The name of the NPM package that provides the plugin.
// */
// "packageName": "@scope/my-rush-plugin",
// /**
// * The name of the plugin. This can be found in the "pluginName"
// * field of the "rush-plugin-manifest.json" file in the NPM package folder.
// */
// "pluginName": "my-plugin-name",
// /**
// * The name of a Rush autoinstaller that will be used for installation, which
// * can be created using "rush init-autoinstaller". Add the plugin's NPM package
// * to the package.json "dependencies" of your autoinstaller, then run
// * "rush update-autoinstaller".
// */
// "autoinstallerName": "rush-plugins"
// }
]
}

View File

@ -40,7 +40,7 @@
// * When creating a release branch in Git, this field should be updated according to the
// * type of release.
// *
// * Valid values are: "prerelease", "release", "minor", "patch", "major"
// * Valid values are: "prerelease", "minor", "patch", "major"
// */
// "nextBump": "prerelease",
//

View File

@ -1 +1 @@
{ "major": 0, "minor": 6, "patch": 99 }
{ "major": 0, "minor": 6, "patch": 108 }

View File

@ -1,5 +1,5 @@
{
"incrementalBuildIgnoredGlobs": ["temp/**"],
"incrementalBuildIgnoredGlobs": ["temp/**", "dist_cache/**", "lib/**"],
"disableBuildCacheForProject": false,
"operationSettings": [

View File

@ -1,5 +1,5 @@
{
"incrementalBuildIgnoredGlobs": ["temp/**"],
"incrementalBuildIgnoredGlobs": ["temp/**", "dist_cache/**", "lib/**"],
"disableBuildCacheForProject": false,
"operationSettings": [

View File

@ -1,11 +1,11 @@
{
"incrementalBuildIgnoredGlobs": ["temp/**"],
"incrementalBuildIgnoredGlobs": ["temp/**", "dist_cache/**", "lib/**"],
"disableBuildCacheForProject": false,
"operationSettings": [
{
"operationName": "build",
"outputFolderNames": ["dist_cache"]
"outputFolderNames": ["dist", "lib", "dist_cache"]
}
]
}

View File

@ -39,9 +39,16 @@
if (last === null) {
last = localStorage.getItem('platform_last_loc')
}
let useDefault = true
if (last !== null) {
navigate(JSON.parse(last))
} else {
const storedLoc = JSON.parse(last)
const key = storedLoc.path?.[0]
if (Array.from(routes.values()).includes(key) || Array.from(routes.keys()).includes(key)) {
useDefault = false
navigate(storedLoc)
}
}
if (useDefault) {
application = getMetadata(uiPlugin.metadata.DefaultApplication)
if (application !== undefined) {
const loc = getCurrentLocation()
@ -187,6 +194,7 @@
// height: var(--app-height);
.antiStatusBar {
-webkit-app-region: drag;
min-height: var(--status-bar-height);
height: var(--status-bar-height);
// min-width: 600px;
@ -214,6 +222,7 @@
user-select: none;
}
.widget {
-webkit-app-region: no-drag;
width: 16px;
height: 16px;
font-size: 14px;

View File

@ -13,7 +13,7 @@
// limitations under the License.
//
import { derived, writable } from 'svelte/store'
import { derived, get, writable } from 'svelte/store'
import { closePopup } from './popups'
import justClone from 'just-clone'
import { Location as PlatformLocation } from './types'
@ -100,7 +100,7 @@ function parseHash (hash: string): string {
// ------------------------
export function getCurrentLocation (): PlatformLocation {
export function getRawCurrentLocation (): PlatformLocation {
return parseLocation(window.location)
}
@ -108,26 +108,47 @@ export function getCurrentResolvedLocation (): PlatformLocation {
return justClone(resolvedLocation)
}
const locationWritable = writable(getCurrentLocation())
window.addEventListener('popstate', () => {
locationWritable.set(getCurrentLocation())
})
declare global {
interface Window {
embeddedPlatform?: boolean
}
}
const embeddedPlatform = window.embeddedPlatform ?? false
const locationWritable = writable(embeddedPlatform ? { path: [] } : getRawCurrentLocation())
export const location = derived(locationWritable, (loc) => loc)
export const resolvedLocationStore = writable(getCurrentLocation())
let resolvedLocation = getCurrentLocation()
console.log('embeddedPlatform', window.embeddedPlatform)
if (!embeddedPlatform) {
window.addEventListener('popstate', () => {
locationWritable.set(getRawCurrentLocation())
})
}
export const location = embeddedPlatform ? locationWritable : derived(locationWritable, (loc) => loc)
export const resolvedLocationStore = writable(getRawCurrentLocation())
let resolvedLocation = getRawCurrentLocation()
export function setResolvedLocation (location: PlatformLocation): void {
resolvedLocation = location
resolvedLocationStore.set(justClone(location))
}
export function getCurrentLocation (): PlatformLocation {
if (embeddedPlatform) {
return justClone(get(locationWritable))
}
return getRawCurrentLocation()
}
export function navigate (location: PlatformLocation, store = true): boolean {
closePopup()
const cur = locationToUrl(getCurrentLocation())
const url = locationToUrl(location)
if (locationToUrl(getCurrentLocation()) !== url) {
if (cur !== url) {
if (store) {
history.pushState(null, '', url)
if (!embeddedPlatform) {
history.pushState(null, '', url)
}
localStorage.setItem('platform_last_loc', JSON.stringify(location))
if (location.path[1] !== undefined) {
localStorage.setItem(`platform_last_loc_${location.path[1]}`, JSON.stringify(location))

View File

@ -18,9 +18,9 @@
import login from '@hcengineering/login'
import notification, { notificationId } from '@hcengineering/notification'
import { BrowserNotificatator, NotificationClientImpl } from '@hcengineering/notification-resources'
import { IntlString, getMetadata, getResource } from '@hcengineering/platform'
import setting from '@hcengineering/setting'
import { IntlString, broadcastEvent, getMetadata, getResource } from '@hcengineering/platform'
import { ActionContext, createQuery, getClient } from '@hcengineering/presentation'
import setting from '@hcengineering/setting'
import {
AnyComponent,
CompAndProps,
@ -65,15 +65,15 @@
import { workspacesStore } from '../utils'
import AccountPopup from './AccountPopup.svelte'
import AppItem from './AppItem.svelte'
import AppSwitcher from './AppSwitcher.svelte'
import Applications from './Applications.svelte'
import Logo from './Logo.svelte'
import NavHeader from './NavHeader.svelte'
import Navigator from './Navigator.svelte'
import SelectWorkspaceMenu from './SelectWorkspaceMenu.svelte'
import SpaceView from './SpaceView.svelte'
import TopMenu from './icons/TopMenu.svelte'
import IconSettings from './icons/Settings.svelte'
import AppSwitcher from './AppSwitcher.svelte'
import TopMenu from './icons/TopMenu.svelte'
let contentPanel: HTMLElement
@ -190,6 +190,7 @@
const title = getMetadata(workbench.metadata.PlatformTitle) ?? 'Platform'
document.title = ws == null ? title : `${ws} - ${title}`
}
broadcastEvent(workbench.event.NotifyTitle, document.title)
}
async function getWindowTitle (loc: Location) {
if (loc.fragment == null) return

View File

@ -9,7 +9,7 @@ import core, {
versionToString
} from '@hcengineering/core'
import login, { loginId } from '@hcengineering/login'
import { addEventListener, getMetadata, getResource, setMetadata } from '@hcengineering/platform'
import { addEventListener, broadcastEvent, getMetadata, getResource, setMetadata } from '@hcengineering/platform'
import presentation, { closeClient, refreshClient, setClient } from '@hcengineering/presentation'
import ui, {
fetchMetadataLocalStorage,
@ -20,6 +20,7 @@ import ui, {
showPopup
} from '@hcengineering/ui'
import ServerManager from './components/ServerManager.svelte'
import plugin from './plugin'
export let versionError: string | undefined = ''
@ -169,6 +170,7 @@ export async function connect (title: string): Promise<Client | undefined> {
}
})
}
await broadcastEvent(plugin.event.NotifyConnection, getCurrentAccount())
return _client
}

View File

@ -130,6 +130,10 @@ export default plugin(workbenchId, {
icon: {
Search: '' as Asset
},
event: {
NotifyConnection: '' as Metadata<string>,
NotifyTitle: '' as Metadata<string>
},
metadata: {
PlatformTitle: '' as Metadata<string>,
ExcludedApplications: '' as Metadata<Ref<Application>[]>,

View File

@ -16,7 +16,7 @@
* path segment in the "$schema" field for all your Rush config files. This will ensure
* correct error-underlining and tab-completion for editors such as VS Code.
*/
"rushVersion": "5.97.1",
"rushVersion": "5.100.1",
/**
* The next field selects which package manager should be installed and determines its version.

View File

@ -24,7 +24,8 @@
"eslint-config-standard-with-typescript": "^23.0.0",
"prettier": "^2.7.1",
"@rushstack/heft": "^0.47.9",
"typescript": "^4.3.5"
"typescript": "^4.3.5",
"@types/node": "~16.11.12"
},
"dependencies": {
"@types/minio": "~7.0.11",

View File

@ -3,6 +3,7 @@
"compilerOptions": {
"rootDir": "./src",
"outDir": "./lib"
"outDir": "./lib",
"types": ["heft-jest", "node"],
}
}

File diff suppressed because one or more lines are too long

View File

@ -9,6 +9,7 @@
"build": "heft build",
"build:watch": "tsc",
"lint:fix": "eslint --fix src",
"bundle": "esbuild src/index.ts --bundle --minify --platform=node > apm.js",
"lint": "eslint src",
"format": "prettier --write src && eslint --fix src"
},

View File

@ -1,6 +1,6 @@
import { program } from 'commander'
import { join } from 'path'
import { syncRushFiles } from './sync'
import { createTemplate } from './template'
console.info('Anticrm Platform Manager')
@ -9,16 +9,17 @@ program.version('0.6.0')
program
.command('rush-sync <root>')
.description('Synchronized rush.js files with platform.')
.action(async (root: string, cmd) => {
await syncRushFiles(process.cwd(), root)
})
program
.command('template-apply <root>')
.description('Create necessary startup packages')
.requiredOption('--root <root>', 'user password', 'platform')
.action(async (root: string, cmd) => {
await createTemplate(process.cwd(), root)
.option('-e, --exclude <exclude>', 'List of exclude patterns to override excludes (comma separated)', '')
.option('-i, --include <include>', 'List of include patterns to override excludes (comma separated)', '')
.option('-s, --source <source>', 'Comma separated list of rush_source.json files', 'rush_source.json')
.action(async (root: string, cmd: { include: string, exclude: string, source: string }) => {
await syncRushFiles(
cmd.source.split(',').map((it) => join(process.cwd(), it.trim())),
process.cwd(),
root,
cmd.include.split(','),
cmd.exclude.split(',')
)
})
program.parse(process.argv)

View File

@ -1,6 +1,6 @@
import { CommentArray, CommentObject, parse, stringify } from 'comment-json'
import { readFile, writeFile } from 'fs/promises'
import { join } from 'path'
import path, { join } from 'path'
interface RushPackage {
packageName: string
@ -8,41 +8,58 @@ interface RushPackage {
shouldPublish: boolean
}
const ignoreProjects = new Set([
'@hcengineering/prod',
'@hcengineering/pod-front',
'@hcengineering/pod-server',
'@hcengineering/pod-account'
])
function platformFilter (root: string): (it: RushPackage) => boolean {
return (it) => {
return !it.projectFolder.startsWith(root)
}
}
export async function syncRushFiles (root: string, platformRoot: string): Promise<void> {
export async function syncRushFiles (
root: string[],
targetRoot: string,
platformRoot: string,
include: string[],
exclude: string[]
): Promise<void> {
const platformJson: CommentObject = parse(
(await readFile(join(root, platformRoot, 'rush.json'))).toString()
(await readFile(join(process.cwd(), platformRoot, 'rush.json'))).toString()
) as CommentObject
const rushjs = join(root, 'rush.json')
const rushjsSource = join(root, 'rush_source.json')
const rushJson: CommentObject = parse((await readFile(rushjsSource)).toString()) as CommentObject
const platformProjecs = (platformJson.projects as unknown as CommentArray<RushPackage>).filter(
(it) => !ignoreProjects.has(it.packageName)
)
const projects = rushJson.projects as unknown as CommentArray<RushPackage>
const rushjs = join(targetRoot, 'rush.json')
const newProjects = projects.filter(platformFilter(platformRoot))
newProjects.push(
...platformProjecs.map((it) => ({
...it,
projectFolder: join(platformRoot, it.projectFolder),
shouldPublish: false
}))
)
const abs = path.resolve(targetRoot).split(path.sep)
rushJson.projects = newProjects as unknown as CommentArray<CommentObject>
const projects: RushPackage[] = []
await writeFile(rushjs, stringify(rushJson, undefined, 2))
for (const prj of [join(platformRoot, 'rush.json'), ...root]) {
const sPath = path.dirname(path.resolve(prj)).split(path.sep)
const diff = path.join(...sPath.slice(abs.length))
const rushJsonSource = (await parse((await readFile(prj)).toString())) as CommentObject
const sprojects = rushJsonSource.projects as unknown as CommentArray<RushPackage>
for (const [k, v] of Object.entries(rushJsonSource)) {
platformJson[k] = v
}
projects
.filter((it) => filterPackage(it, include, exclude))
.push(
...sprojects.map((it) => ({
...it,
projectFolder: join(diff, it.projectFolder),
shouldPublish: diff === '.' ? it.shouldPublish : false
}))
)
}
platformJson.projects = projects as unknown as CommentArray<CommentObject>
await writeFile(rushjs, stringify(platformJson, undefined, 2))
}
function filterPackage (it: RushPackage, include: string[], exclude: string[]): boolean {
const pkgName = it.packageName
for (const i of include) {
if (pkgName.includes(i)) {
return true
}
}
for (const i of exclude) {
if (pkgName.includes(i)) {
return false
}
}
return true
}