Skip to content

Commit

Permalink
Merge branch 'edge' into opentrons-ai-client-landing-page
Browse files Browse the repository at this point in the history
  • Loading branch information
fbelginetw committed Oct 21, 2024
2 parents 2514383 + d9dd918 commit fde8b2c
Show file tree
Hide file tree
Showing 57 changed files with 4,288 additions and 1,015 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/app-test-build-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ jobs:
strategy:
matrix:
os: ['windows-2022', 'ubuntu-22.04', 'macos-latest']
name: 'opentrons app backend unit tests on ${{matrix.os}}'
shell: ['app-shell', 'app-shell-odd', 'discovery-client']
exclude:
- os: 'windows-2022'
shell: 'app-shell-odd'
name: 'opentrons ${{matrix.shell}} unit tests on ${{matrix.os}}'
timeout-minutes: 60
runs-on: ${{ matrix.os }}
steps:
Expand Down Expand Up @@ -144,7 +148,7 @@ jobs:
yarn config set cache-folder ${{ github.workspace }}/.yarn-cache
make setup-js
- name: 'test native(er) packages'
run: make test-js-internal tests="app-shell/src app-shell-odd/src discovery-client/src" cov_opts="--coverage=true"
run: make test-js-internal tests="${{}matrix.shell}/src" cov_opts="--coverage=true"
- name: 'Upload coverage report'
uses: 'codecov/codecov-action@v3'
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ jobs:
yarn config set cache-folder ${{ github.workspace }}/.yarn-cache
make setup-js
- name: 'build'
env:
# inject dev id since this is for staging
OT_AI_CLIENT_MIXPANEL_ID: ${{ secrets.OT_AI_CLIENT_MIXPANEL_DEV_ID }}
run: |
make -C opentrons-ai-client build-staging
- name: Configure AWS Credentials
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@ on:
paths:
- 'Makefile'
- 'opentrons-ai-client/**/*'
- 'components/**/*'
- '*.js'
- '*.json'
- 'yarn.lock'
- '.github/workflows/app-test-build-deploy.yaml'
- '.github/workflows/utils.js'
- 'components/**'
- 'shared-data/**'
- '.github/workflows/opentrons-ai-client-test.yml'
branches:
- '**'
tags:
Expand All @@ -24,10 +21,9 @@ on:
paths:
- 'Makefile'
- 'opentrons-ai-client/**/*'
- 'components/**/*'
- '*.js'
- '*.json'
- 'yarn.lock'
- 'components/**'
- 'shared-data/**'
- '.github/workflows/opentrons-ai-client-test.yml'
workflow_dispatch:

concurrency:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/opentrons-ai-production-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ jobs:
yarn config set cache-folder ${{ github.workspace }}/.yarn-cache
make setup-js
- name: 'build'
env:
OT_AI_CLIENT_MIXPANEL_ID: ${{ secrets.OT_AI_CLIENT_MIXPANEL_ID }}
run: |
make -C opentrons-ai-client build-production
- name: Configure AWS Credentials
Expand Down
1 change: 1 addition & 0 deletions app-shell-odd/src/__tests__/http.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { Request, Response } from 'node-fetch'

vi.mock('../config')
vi.mock('node-fetch')
vi.mock('../log')

describe('app-shell main http module', () => {
beforeEach(() => {
Expand Down
47 changes: 0 additions & 47 deletions app-shell-odd/src/__tests__/update.test.ts

This file was deleted.

2 changes: 2 additions & 0 deletions app-shell-odd/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ import type {
export const configInitialized = (config: Config): ConfigInitializedAction => ({
type: CONFIG_INITIALIZED,
payload: { config },
meta: { shell: true },
})

// config value has been updated
Expand All @@ -128,6 +129,7 @@ export const configValueUpdated = (
): ConfigValueUpdatedAction => ({
type: VALUE_UPDATED,
payload: { path, value },
meta: { shell: true },
})

export const customLabwareList = (
Expand Down
16 changes: 10 additions & 6 deletions app-shell-odd/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import get from 'lodash/get'
import forEach from 'lodash/forEach'
import mergeOptions from 'merge-options'
import yargsParser from 'yargs-parser'

import { UI_INITIALIZED } from '../constants'
import * as Cfg from '../constants'
import { configInitialized, configValueUpdated } from '../actions'
import systemd from '../systemd'
import { createLogger } from '../log'
import { DEFAULTS_V12, migrate } from './migrate'
import { shouldUpdate, getNextValue } from './update'
import { setUserDataPath } from '../early'

import type {
ConfigV12,
Expand All @@ -24,8 +24,6 @@ import type { Config, Overrides } from './types'

export * from './types'

export const ODD_DIR = '/data/ODD'

// make sure all arguments are included in production
const argv = process.argv0.endsWith('defaultApp')
? process.argv.slice(2)
Expand All @@ -48,8 +46,7 @@ const store = (): Store => {
// perform store migration if loading for the first time
_store = (new Store({
defaults: DEFAULTS_V12,
// dont overwrite config dir if in dev mode because it causes issues
...(process.env.NODE_ENV === 'production' && { cwd: ODD_DIR }),
cwd: setUserDataPath(),
}) as unknown) as Store<Config>
_store.store = migrate((_store.store as unknown) as ConfigV12)
}
Expand All @@ -66,7 +63,14 @@ const log = (): Logger => _log ?? (_log = createLogger('config'))
export function registerConfig(dispatch: Dispatch): (action: Action) => void {
return function handleIncomingAction(action: Action) {
if (action.type === UI_INITIALIZED) {
log().info('initializing configuration')
dispatch(configInitialized(getFullConfig()))
log().info(
`flow route: ${
getConfig('onDeviceDisplaySettings').unfinishedUnboxingFlowRoute
}`
)
log().info('configuration initialized')
} else if (
action.type === Cfg.UPDATE_VALUE ||
action.type === Cfg.RESET_VALUE ||
Expand Down Expand Up @@ -120,8 +124,8 @@ export function getOverrides(path?: string): unknown {
return path != null ? get(overrides(), path) : overrides()
}

export function getConfig<P extends keyof Config>(path: P): Config[P]
export function getConfig(): Config
export function getConfig<P extends keyof Config>(path: P): Config[P]
export function getConfig(path?: any): any {
const result = store().get(path)
const over = getOverrides(path as string | undefined)
Expand Down
2 changes: 2 additions & 0 deletions app-shell-odd/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,5 @@ export const FAILURE_STATUSES = {
} as const

export const SEND_FILE_PATHS: 'shell:SEND_FILE_PATHS' = 'shell:SEND_FILE_PATHS'

export const ODD_DATA_DIR = '/data/ODD'
22 changes: 22 additions & 0 deletions app-shell-odd/src/early.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// things intended to execute early in app-shell initialization
// do as little as possible in this file and do none of it at import time

import { app } from 'electron'
import { ODD_DATA_DIR } from './constants'

let path: string

export const setUserDataPath = (): string => {
if (path == null) {
console.log(
`node env is ${process.env.NODE_ENV}, path is ${app.getPath('userData')}`
)
if (process.env.NODE_ENV === 'production') {
console.log(`setting app path to ${ODD_DATA_DIR}`)
app.setPath('userData', ODD_DATA_DIR)
}
path = app.getPath('userData')
console.log(`app path becomes ${app.getPath('userData')}`)
}
return app.getPath('userData')
}
52 changes: 43 additions & 9 deletions app-shell-odd/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,30 @@ import FormData from 'form-data'
import { Transform } from 'stream'

import { HTTP_API_VERSION } from './constants'
import { createLogger } from './log'

import type { Readable } from 'stream'
import type { Request, RequestInit, Response } from 'node-fetch'

const log = createLogger('http')

type RequestInput = Request | string

export interface DownloadProgress {
downloaded: number
size: number | null
}

export class LocalAbortError extends Error {
declare readonly name: 'LocalAbortError'
declare readonly type: 'aborted'
constructor(message: string) {
super(message)
this.name = 'LocalAbortError'
this.type = 'aborted'
}
}

export function fetch(
input: RequestInput,
init?: RequestInit
Expand All @@ -35,21 +48,29 @@ export function fetch(
})
}

export function fetchJson<Body>(input: RequestInput): Promise<Body> {
return fetch(input).then(response => response.json())
export function fetchJson<Body>(
input: RequestInput,
init?: RequestInit
): Promise<Body> {
return fetch(input, init).then(response => response.json())
}

export function fetchText(input: Request, init?: RequestInit): Promise<string> {
return fetch(input, init).then(response => response.text())
}

export function fetchText(input: Request): Promise<string> {
return fetch(input).then(response => response.text())
export interface FetchToFileOptions {
onProgress: (progress: DownloadProgress) => unknown
signal: AbortSignal
}

// TODO(mc, 2019-07-02): break this function up and test its components
export function fetchToFile(
input: RequestInput,
destination: string,
options?: Partial<{ onProgress: (progress: DownloadProgress) => unknown }>
options?: Partial<FetchToFileOptions>
): Promise<string> {
return fetch(input).then(response => {
return fetch(input, { signal: options?.signal }).then(response => {
let downloaded = 0
const size = Number(response.headers.get('Content-Length')) || null

Expand All @@ -75,13 +96,26 @@ export function fetchToFile(
// pump calls stream.pipe, handles teardown if streams error, and calls
// its callbacks when the streams are done
pump(inputStream, progressReader, outputStream, error => {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (error) {
const handleError = (problem: Error): void => {
// if we error out, delete the temp dir to clean up
return remove(destination).then(() => {
log.error(`Aborting fetchToFile: ${problem.name}: ${problem.message}`)
remove(destination).then(() => {
reject(error)
})
}
const listener = (): void => {
handleError(
new LocalAbortError(
(options?.signal?.reason as string | null) ?? 'aborted'
)
)
}
options?.signal?.addEventListener('abort', listener, { once: true })
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (error) {
handleError(error)
}
options?.signal?.removeEventListener('abort', listener, {})
resolve(destination)
})
})
Expand Down
4 changes: 2 additions & 2 deletions app-shell-odd/src/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import path from 'path'
import dateFormat from 'dateformat'
import winston from 'winston'

import { setUserDataPath } from './early'
import { getConfig } from './config'

import type Transport from 'winston-transport'
import type { Config } from './config'

const ODD_DIR = '/data/ODD'
const LOG_DIR = path.join(ODD_DIR, 'logs')
const LOG_DIR = path.join(setUserDataPath(), 'logs')
const ERROR_LOG = path.join(LOG_DIR, 'error.log')
const COMBINED_LOG = path.join(LOG_DIR, 'combined.log')

Expand Down
Loading

0 comments on commit fde8b2c

Please sign in to comment.